diff --git a/gui_data/app_size_values.py b/gui_data/app_size_values.py new file mode 100644 index 0000000000000000000000000000000000000000..b174c60e12e7b61cd0ed55e43211c9fdceebb1f9 --- /dev/null +++ b/gui_data/app_size_values.py @@ -0,0 +1,121 @@ +import os +from screeninfo import get_monitors +from PIL import Image +from PIL import ImageTk + +def get_screen_height(): + monitors = get_monitors() + if len(monitors) == 0: + raise Exception("Failed to get screen height") + return monitors[0].height + +SCREEN_SIZE_VALUES = { + "normal": { + "credits_img":(100, 100), + ## App Size + 'IMAGE_HEIGHT': 140, + 'FILEPATHS_HEIGHT': 75, + 'OPTIONS_HEIGHT': 262, + 'CONVERSIONBUTTON_HEIGHT': 30, + 'COMMAND_HEIGHT': 141, + 'PROGRESS_HEIGHT': 25, + 'PADDING': 7, + }, + "small": { + "credits_img":(50, 50), + ## App Size + 'IMAGE_HEIGHT': 135, + 'FILEPATHS_HEIGHT': 85, + 'OPTIONS_HEIGHT': 274, + 'CONVERSIONBUTTON_HEIGHT': 35, + 'COMMAND_HEIGHT': 80, + 'PROGRESS_HEIGHT': 6, + 'PADDING': 5, + }, + "medium": { + "credits_img":(50, 50), + ## App Size + 'IMAGE_HEIGHT': 135, + 'FILEPATHS_HEIGHT': 85, + 'OPTIONS_HEIGHT': 274, + 'CONVERSIONBUTTON_HEIGHT': 20, + 'COMMAND_HEIGHT': 115, + 'PROGRESS_HEIGHT': 9, + 'PADDING': 7, + }, +} + + +try: + if get_screen_height() >= 900: + determined_size = SCREEN_SIZE_VALUES["normal"] + elif get_screen_height() <= 720: + determined_size = SCREEN_SIZE_VALUES["small"] + else: + determined_size = SCREEN_SIZE_VALUES["medium"] +except: + determined_size = SCREEN_SIZE_VALUES["normal"] + +class ImagePath(): + def __init__(self, base_path): + + img_path = os.path.join(base_path, 'gui_data', 'img') + credits_path = os.path.join(img_path, 'credits.png') + donate_path = os.path.join(img_path, 'donate.png') + download_path = os.path.join(img_path, 'download.png') + efile_path = os.path.join(img_path, 'File.png') + help_path = os.path.join(img_path, 'help.png') + key_path = os.path.join(img_path, 'key.png') + stop_path = os.path.join(img_path, 'stop.png') + play_path = os.path.join(img_path, 'play.png') + pause_path = os.path.join(img_path, 'pause.png') + self.banner_path = os.path.join(img_path, 'UVR-banner.png') + + self.efile_img = self.open_image(path=efile_path,size=(20, 20)) + self.stop_img = self.open_image(path=stop_path, size=(20, 20)) + self.play_img = self.open_image(path=play_path, size=(20, 20)) + self.pause_img = self.open_image(path=pause_path, size=(20, 20)) + self.help_img = self.open_image(path=help_path, size=(20, 20)) + self.download_img = self.open_image(path=download_path, size=(30, 30)) + self.donate_img = self.open_image(path=donate_path, size=(30, 30)) + self.key_img = self.open_image(path=key_path, size=(30, 30)) + self.credits_img = self.open_image(path=credits_path, size=determined_size["credits_img"]) + + def open_image(self, path: str, size: tuple = None, keep_aspect: bool = True, rotate: int = 0) -> ImageTk.PhotoImage: + """ + Open the image on the path and apply given settings\n + Paramaters: + path(str): + Absolute path of the image + size(tuple): + first value - width + second value - height + keep_aspect(bool): + keep aspect ratio of image and resize + to maximum possible width and height + (maxima are given by size) + rotate(int): + clockwise rotation of image + Returns(ImageTk.PhotoImage): + Image of path + """ + img = Image.open(path).convert(mode='RGBA') + ratio = img.height/img.width + img = img.rotate(angle=-rotate) + if size is not None: + size = (int(size[0]), int(size[1])) + if keep_aspect: + img = img.resize((size[0], int(size[0] * ratio)), Image.ANTIALIAS) + else: + img = img.resize(size, Image.ANTIALIAS) + + return ImageTk.PhotoImage(img) + +class AdjustedValues(): + IMAGE_HEIGHT = determined_size["IMAGE_HEIGHT"] + FILEPATHS_HEIGHT = determined_size["FILEPATHS_HEIGHT"] + OPTIONS_HEIGHT = determined_size["OPTIONS_HEIGHT"] + CONVERSIONBUTTON_HEIGHT = determined_size["CONVERSIONBUTTON_HEIGHT"] + COMMAND_HEIGHT = determined_size["COMMAND_HEIGHT"] + PROGRESS_HEIGHT = determined_size["PROGRESS_HEIGHT"] + PADDING = determined_size["PADDING"] diff --git a/gui_data/change_log.txt b/gui_data/change_log.txt new file mode 100644 index 0000000000000000000000000000000000000000..be400542bc4e0d0f410844f3b55a856567c9d42a --- /dev/null +++ b/gui_data/change_log.txt @@ -0,0 +1,93 @@ +Most Recent Changes: + +~ Fixed Download Center model list issue. +~ Fixed audio clip in ensemble mode. +~ Fixed output model name issue in ensemble mode. +~ Added "Batch Mode" for MDX-Net to increase performance. + ~ Batch Mode is more memory efficient. + ~ Batch Mode produces the best output, regardless of batch size. +~ Added Batch Mode for VR Architecture. +~ Added Mixer Mode for Demucs. + ~ This option may improve separation for some 4-stem models. + +Fixes & Changes going from UVR v5.4 to v5.5: + +~ The progress bar is now fully synced up with every process in the application. +~ Fixed low-resolution icon. +~ Added the ability to download models manually if the application can't connect + to the internet. +~ Drag-n-drop is functional across all os platforms. +~ Resolved mp3 tag issue in MacOS version. + +Performance: + +~ Model load times are faster. +~ Importing/exporting audio files is faster. + +MacOS M1 Notes: + +~ The GPU Conversion checkbox will enable MPS for GPU acceleration. However, + only the VR Architecture models are currently compatible with it. + +New Options: + +~ Select Saved Settings option - Allows the user to save the current settings + of the whole application. You can also load a saved setting or reset them to + the default. +~ Right-click menu - Allows for quick access to important options. +~ Help Hints option - When enabled, users can hover over options to see a pop-up + text that describes that option. The right-clicking option also allows copying + the "Help Hint" text. +~ Secondary Model Mode - This option is an expanded version of the "Demucs Model" + option that was only available to MDX-Net. Except now, this option is available + in all three AI Networks and for any stem. Any model can now be Secondary, and + the user can choose the amount of influence it has on the final result. +~ Robust caching for ensemble mode, allowing for much faster processing times. +~ Clicking the "Input" field will pop up a window allowing the user to review the selected audio inputs. Within this menu, users can: + ~ Remove inputs. + ~ Verify inputs. + ~ Create samples of chosen inputs. +~ "Sample Mode" option - Allows the user to process only part of a track to sample + settings or a model without running a full conversion. + ~ The number in the parentheses is the current number of seconds the generated + sample will be. + ~ You can choose the number of seconds to extract from the track in the "Additional + Settings" menu. + +VR Architecture: + +~ Ability to toggle "High-End Processing." +~ Ability to change the post-processing threshold. +~ Support for the latest VR architecture + ~ Crop Size and Batch Size are specifically for models using the latest + architecture only. + +MDX-NET: + +~ Denoise Output option results in cleaner results, + but the processing time will be longer. This option has replaced Noise Reduction. +~ Spectral Inversion option uses spectral inversion techniques for a + cleaner secondary stem result. This option may slow down the audio export process. +~ Secondary stem now has the same frequency cut-off as the main stem. + +Demucs: + +~ Demucs v4 models are now supported, including the 6-stem model. +~ Ability to combine remaining stems instead of inverting selected stem with the + mixture only when a user does not select "All Stems". +~ A Pre-process model that allows the user to run an inference through a robust + vocal or instrumental model and separate the remaining stems from its generated + instrumental mix. This option can significantly reduce vocal bleed in other + Demucs-generated non-vocal stems. + ~ The Pre-process model is intended for Demucs separations for all stems except + vocals and instrumentals. + +Ensemble Mode: + +~ Ensemble Mode has been extended to include the following: + ~ Averaging is a new algorithm that averages the final results. + ~ Unlimited models in the ensemble. + ~ Ability to save different ensembles. + ~ Ability to ensemble outputs for all individual stem types. + ~ Ability to choose unique ensemble algorithms. + ~ Ability to ensemble all 4 Demucs stems at once. \ No newline at end of file diff --git a/gui_data/complete_chime.wav b/gui_data/complete_chime.wav new file mode 100644 index 0000000000000000000000000000000000000000..c51ae89cbc82f110d890cd945139fd9dd9dd4640 Binary files /dev/null and b/gui_data/complete_chime.wav differ diff --git a/gui_data/constants.py b/gui_data/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..c5ac0e98291d16d9c123402fc747a47a5f7f9b1a --- /dev/null +++ b/gui_data/constants.py @@ -0,0 +1,1147 @@ +import platform + +#Platform Details +OPERATING_SYSTEM = platform.system() +SYSTEM_ARCH = platform.platform() +SYSTEM_PROC = platform.processor() +ARM = 'arm' + +#Main Font +MAIN_FONT_NAME = "Century Gothic" + +#Model Types +VR_ARCH_TYPE = 'VR Arc' +MDX_ARCH_TYPE = 'MDX-Net' +DEMUCS_ARCH_TYPE = 'Demucs' +VR_ARCH_PM = 'VR Architecture' +ENSEMBLE_MODE = 'Ensemble Mode' +ENSEMBLE_STEM_CHECK = 'Ensemble Stem' +SECONDARY_MODEL = 'Secondary Model' +DEMUCS_6_STEM_MODEL = 'htdemucs_6s' + +DEMUCS_V3_ARCH_TYPE = 'Demucs v3' +DEMUCS_V4_ARCH_TYPE = 'Demucs v4' +DEMUCS_NEWER_ARCH_TYPES = [DEMUCS_V3_ARCH_TYPE, DEMUCS_V4_ARCH_TYPE] + +DEMUCS_V1 = 'v1' +DEMUCS_V2 = 'v2' +DEMUCS_V3 = 'v3' +DEMUCS_V4 = 'v4' + +DEMUCS_V1_TAG = 'v1 | ' +DEMUCS_V2_TAG = 'v2 | ' +DEMUCS_V3_TAG = 'v3 | ' +DEMUCS_V4_TAG = 'v4 | ' +DEMUCS_NEWER_TAGS = [DEMUCS_V3_TAG, DEMUCS_V4_TAG] + +DEMUCS_VERSION_MAPPER = { + DEMUCS_V1:DEMUCS_V1_TAG, + DEMUCS_V2:DEMUCS_V2_TAG, + DEMUCS_V3:DEMUCS_V3_TAG, + DEMUCS_V4:DEMUCS_V4_TAG} + +#Download Center +DOWNLOAD_FAILED = 'Download Failed' +DOWNLOAD_STOPPED = 'Download Stopped' +DOWNLOAD_COMPLETE = 'Download Complete' +DOWNLOAD_UPDATE_COMPLETE = 'Update Download Complete' +SETTINGS_MENU_EXIT = 'exit' +NO_CONNECTION = 'No Internet Connection' +VIP_SELECTION = 'VIP:' +DEVELOPER_SELECTION = 'VIP:' +NO_NEW_MODELS = 'All Available Models Downloaded' +ENSEMBLE_PARTITION = ': ' +NO_MODEL = 'No Model Selected' +CHOOSE_MODEL = 'Choose Model' +SINGLE_DOWNLOAD = 'Downloading Item 1/1...' +DOWNLOADING_ITEM = 'Downloading Item' +FILE_EXISTS = 'File already exists!' +DOWNLOADING_UPDATE = 'Downloading Update...' +DOWNLOAD_MORE = 'Download More Models' + +#Menu Options + +AUTO_SELECT = 'Auto' + +#LINKS +DOWNLOAD_CHECKS = "https://raw.githubusercontent.com/TRvlvr/application_data/main/filelists/download_checks.json" +MDX_MODEL_DATA_LINK = "https://raw.githubusercontent.com/TRvlvr/application_data/main/mdx_model_data/model_data.json" +VR_MODEL_DATA_LINK = "https://raw.githubusercontent.com/TRvlvr/application_data/main/vr_model_data/model_data.json" + +DEMUCS_MODEL_NAME_DATA_LINK = "https://raw.githubusercontent.com/TRvlvr/application_data/main/demucs_model_data/model_name_mapper.json" +MDX_MODEL_NAME_DATA_LINK = "https://raw.githubusercontent.com/TRvlvr/application_data/main/mdx_model_data/model_name_mapper.json" + +DONATE_LINK_BMAC = "https://www.buymeacoffee.com/uvr5" +DONATE_LINK_PATREON = "https://www.patreon.com/uvr" + +#DOWNLOAD REPOS +NORMAL_REPO = "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/" +UPDATE_REPO = "https://github.com/TRvlvr/model_repo/releases/download/uvr_update_patches/" + +UPDATE_MAC_ARM_REPO = "https://github.com/Anjok07/ultimatevocalremovergui/releases/download/v5.5.0/Ultimate_Vocal_Remover_v5_5_MacOS_arm64.dmg" +UPDATE_MAC_X86_64_REPO = "https://github.com/Anjok07/ultimatevocalremovergui/releases/download/v5.5.0/Ultimate_Vocal_Remover_v5_5_MacOS_x86_64.dmg" +UPDATE_LINUX_REPO = "https://github.com/Anjok07/ultimatevocalremovergui#linux-installation" +UPDATE_REPO = "https://github.com/TRvlvr/model_repo/releases/download/uvr_update_patches/" + +ISSUE_LINK = 'https://github.com/Anjok07/ultimatevocalremovergui/issues/new' +VIP_REPO = b'\xf3\xc2W\x19\x1foI)\xc2\xa9\xcc\xb67(Z\xf5',\ + b'gAAAAABjQAIQ-NpNMMxMedpKHHb7ze_nqB05hw0YhbOy3pFzuzDrfqumn8_qvraxEoUpZC5ZXC0gGvfDxFMqyq9VWbYKlA67SUFI_wZB6QoVyGI581vs7kaGfUqlXHIdDS6tQ_U-BfjbEAK9EU_74-R2zXjz8Xzekw==' +NO_CODE = 'incorrect_code' + +#Extensions + +ONNX = '.onnx' +CKPT = '.ckpt' +YAML = '.yaml' +PTH = '.pth' +TH_EXT = '.th' +JSON = '.json' + +#GUI Buttons + +START_PROCESSING = 'Start Processing' +WAIT_PROCESSING = 'Please wait...' +STOP_PROCESSING = 'Halting process, please wait...' +LOADING_MODELS = 'Loading models...' + +#---Messages and Logs---- + +MISSING_MODEL = 'missing' +MODEL_PRESENT = 'present' + +UNRECOGNIZED_MODEL = 'Unrecognized Model Detected', ' is an unrecognized model.\n\n' + \ + 'Would you like to select the correct parameters before continuing?' + +STOP_PROCESS_CONFIRM = 'Confirmation', 'You are about to stop all active processes.\n\nAre you sure you wish to continue?' +NO_ENSEMBLE_SELECTED = 'No Models Selected', 'Please select ensemble and try again.' +PICKLE_CORRU = 'File Corrupted', 'Unable to load this ensemble.\n\n' + \ + 'Would you like to remove this ensemble from your list?' +DELETE_ENS_ENTRY = 'Confirm Removal', 'Are you sure you want to remove this entry?' + +ALL_STEMS = 'All Stems' +VOCAL_STEM = 'Vocals' +INST_STEM = 'Instrumental' +OTHER_STEM = 'Other' +BASS_STEM = 'Bass' +DRUM_STEM = 'Drums' +GUITAR_STEM = 'Guitar' +PIANO_STEM = 'Piano' +SYNTH_STEM = 'Synthesizer' +STRINGS_STEM = 'Strings' +WOODWINDS_STEM = 'Woodwinds' +BRASS_STEM = 'Brass' +WIND_INST_STEM = 'Wind Inst' +NO_OTHER_STEM = 'No Other' +NO_BASS_STEM = 'No Bass' +NO_DRUM_STEM = 'No Drums' +NO_GUITAR_STEM = 'No Guitar' +NO_PIANO_STEM = 'No Piano' +NO_SYNTH_STEM = 'No Synthesizer' +NO_STRINGS_STEM = 'No Strings' +NO_WOODWINDS_STEM = 'No Woodwinds' +NO_WIND_INST_STEM = 'No Wind Inst' +NO_BRASS_STEM = 'No Brass' +PRIMARY_STEM = 'Primary Stem' +SECONDARY_STEM = 'Secondary Stem' + +#Other Constants +DEMUCS_2_SOURCE = ["instrumental", "vocals"] +DEMUCS_4_SOURCE = ["drums", "bass", "other", "vocals"] + +DEMUCS_2_SOURCE_MAPPER = { + INST_STEM: 0, + VOCAL_STEM: 1} + +DEMUCS_4_SOURCE_MAPPER = { + BASS_STEM: 0, + DRUM_STEM: 1, + OTHER_STEM: 2, + VOCAL_STEM: 3} + +DEMUCS_6_SOURCE_MAPPER = { + BASS_STEM: 0, + DRUM_STEM: 1, + OTHER_STEM: 2, + VOCAL_STEM: 3, + GUITAR_STEM:4, + PIANO_STEM:5} + +DEMUCS_4_SOURCE_LIST = [BASS_STEM, DRUM_STEM, OTHER_STEM, VOCAL_STEM] +DEMUCS_6_SOURCE_LIST = [BASS_STEM, DRUM_STEM, OTHER_STEM, VOCAL_STEM, GUITAR_STEM, PIANO_STEM] + +DEMUCS_UVR_MODEL = 'UVR_Model' + +CHOOSE_STEM_PAIR = 'Choose Stem Pair' + +STEM_SET_MENU = (VOCAL_STEM, + INST_STEM, + OTHER_STEM, + BASS_STEM, + DRUM_STEM, + GUITAR_STEM, + PIANO_STEM, + SYNTH_STEM, + STRINGS_STEM, + WOODWINDS_STEM, + BRASS_STEM, + WIND_INST_STEM, + NO_OTHER_STEM, + NO_BASS_STEM, + NO_DRUM_STEM, + NO_GUITAR_STEM, + NO_PIANO_STEM, + NO_SYNTH_STEM, + NO_STRINGS_STEM, + NO_WOODWINDS_STEM, + NO_BRASS_STEM, + NO_WIND_INST_STEM) + +STEM_PAIR_MAPPER = { + VOCAL_STEM: INST_STEM, + INST_STEM: VOCAL_STEM, + OTHER_STEM: NO_OTHER_STEM, + BASS_STEM: NO_BASS_STEM, + DRUM_STEM: NO_DRUM_STEM, + GUITAR_STEM: NO_GUITAR_STEM, + PIANO_STEM: NO_PIANO_STEM, + SYNTH_STEM: NO_SYNTH_STEM, + STRINGS_STEM: NO_STRINGS_STEM, + WOODWINDS_STEM: NO_WOODWINDS_STEM, + BRASS_STEM: NO_BRASS_STEM, + WIND_INST_STEM: NO_WIND_INST_STEM, + NO_OTHER_STEM: OTHER_STEM, + NO_BASS_STEM: BASS_STEM, + NO_DRUM_STEM: DRUM_STEM, + NO_GUITAR_STEM: GUITAR_STEM, + NO_PIANO_STEM: PIANO_STEM, + NO_SYNTH_STEM: SYNTH_STEM, + NO_STRINGS_STEM: STRINGS_STEM, + NO_WOODWINDS_STEM: WOODWINDS_STEM, + NO_BRASS_STEM: BRASS_STEM, + NO_WIND_INST_STEM: WIND_INST_STEM, + PRIMARY_STEM: SECONDARY_STEM} + +NON_ACCOM_STEMS = ( + VOCAL_STEM, + OTHER_STEM, + BASS_STEM, + DRUM_STEM, + GUITAR_STEM, + PIANO_STEM, + SYNTH_STEM, + STRINGS_STEM, + WOODWINDS_STEM, + BRASS_STEM, + WIND_INST_STEM) + +MDX_NET_FREQ_CUT = [VOCAL_STEM, INST_STEM] + +DEMUCS_4_STEM_OPTIONS = (ALL_STEMS, VOCAL_STEM, OTHER_STEM, BASS_STEM, DRUM_STEM) +DEMUCS_6_STEM_OPTIONS = (ALL_STEMS, VOCAL_STEM, OTHER_STEM, BASS_STEM, DRUM_STEM, GUITAR_STEM, PIANO_STEM) +DEMUCS_2_STEM_OPTIONS = (VOCAL_STEM, INST_STEM) +DEMUCS_4_STEM_CHECK = (OTHER_STEM, BASS_STEM, DRUM_STEM) + +#Menu Dropdowns + +VOCAL_PAIR = f'{VOCAL_STEM}/{INST_STEM}' +INST_PAIR = f'{INST_STEM}/{VOCAL_STEM}' +OTHER_PAIR = f'{OTHER_STEM}/{NO_OTHER_STEM}' +DRUM_PAIR = f'{DRUM_STEM}/{NO_DRUM_STEM}' +BASS_PAIR = f'{BASS_STEM}/{NO_BASS_STEM}' +FOUR_STEM_ENSEMBLE = '4 Stem Ensemble' + +ENSEMBLE_MAIN_STEM = (CHOOSE_STEM_PAIR, VOCAL_PAIR, OTHER_PAIR, DRUM_PAIR, BASS_PAIR, FOUR_STEM_ENSEMBLE) + +MIN_SPEC = 'Min Spec' +MAX_SPEC = 'Max Spec' +AUDIO_AVERAGE = 'Average' + +MAX_MIN = f'{MAX_SPEC}/{MIN_SPEC}' +MAX_MAX = f'{MAX_SPEC}/{MAX_SPEC}' +MAX_AVE = f'{MAX_SPEC}/{AUDIO_AVERAGE}' +MIN_MAX = f'{MIN_SPEC}/{MAX_SPEC}' +MIN_MIX = f'{MIN_SPEC}/{MIN_SPEC}' +MIN_AVE = f'{MIN_SPEC}/{AUDIO_AVERAGE}' +AVE_MAX = f'{AUDIO_AVERAGE}/{MAX_SPEC}' +AVE_MIN = f'{AUDIO_AVERAGE}/{MIN_SPEC}' +AVE_AVE = f'{AUDIO_AVERAGE}/{AUDIO_AVERAGE}' + +ENSEMBLE_TYPE = (MAX_MIN, MAX_MAX, MAX_AVE, MIN_MAX, MIN_MIX, MIN_AVE, AVE_MAX, AVE_MIN, AVE_AVE) +ENSEMBLE_TYPE_4_STEM = (MAX_SPEC, MIN_SPEC, AUDIO_AVERAGE) + +BATCH_MODE = 'Batch Mode' +BETA_VERSION = 'BETA' +DEF_OPT = 'Default' + +CHUNKS = (AUTO_SELECT, '1', '5', '10', '15', '20', + '25', '30', '35', '40', '45', '50', + '55', '60', '65', '70', '75', '80', + '85', '90', '95', 'Full') + +BATCH_SIZE = (DEF_OPT, '2', '3', '4', '5', + '6', '7', '8', '9', '10') + +VOL_COMPENSATION = (AUTO_SELECT, '1.035', '1.08') + +MARGIN_SIZE = ('44100', '22050', '11025') + +AUDIO_TOOLS = 'Audio Tools' + +MANUAL_ENSEMBLE = 'Manual Ensemble' +TIME_STRETCH = 'Time Stretch' +CHANGE_PITCH = 'Change Pitch' +ALIGN_INPUTS = 'Align Inputs' + +if OPERATING_SYSTEM == 'Windows' or OPERATING_SYSTEM == 'Darwin': + AUDIO_TOOL_OPTIONS = (MANUAL_ENSEMBLE, TIME_STRETCH, CHANGE_PITCH, ALIGN_INPUTS) +else: + AUDIO_TOOL_OPTIONS = (MANUAL_ENSEMBLE, ALIGN_INPUTS) + +MANUAL_ENSEMBLE_OPTIONS = (MIN_SPEC, MAX_SPEC, AUDIO_AVERAGE) + +PROCESS_METHODS = (VR_ARCH_PM, MDX_ARCH_TYPE, DEMUCS_ARCH_TYPE, ENSEMBLE_MODE, AUDIO_TOOLS) + +DEMUCS_SEGMENTS = ('Default', '1', '5', '10', '15', '20', + '25', '30', '35', '40', '45', '50', + '55', '60', '65', '70', '75', '80', + '85', '90', '95', '100') + +DEMUCS_SHIFTS = (0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, + 18, 19, 20) + +DEMUCS_OVERLAP = (0.25, 0.50, 0.75, 0.99) + +VR_AGGRESSION = (1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, + 18, 19, 20) + +VR_WINDOW = ('320', '512','1024') +VR_CROP = ('256', '512', '1024') +POST_PROCESSES_THREASHOLD_VALUES = ('0.1', '0.2', '0.3') + +MDX_POP_PRO = ('MDX-NET_Noise_Profile_14_kHz', 'MDX-NET_Noise_Profile_17_kHz', 'MDX-NET_Noise_Profile_Full_Band') +MDX_POP_STEMS = ('Vocals', 'Instrumental', 'Other', 'Drums', 'Bass') +MDX_POP_NFFT = ('4096', '5120', '6144', '7680', '8192', '16384') +MDX_POP_DIMF = ('2048', '3072', '4096') + +SAVE_ENSEMBLE = 'Save Ensemble' +CLEAR_ENSEMBLE = 'Clear Selection(s)' +MENU_SEPARATOR = 35*'•' +CHOOSE_ENSEMBLE_OPTION = 'Choose Option' + +INVALID_ENTRY = 'Invalid Input, Please Try Again' +ENSEMBLE_INPUT_RULE = '1. Only letters, numbers, spaces, and dashes allowed.\n2. No dashes or spaces at the start or end of input.' + +ENSEMBLE_OPTIONS = (SAVE_ENSEMBLE, CLEAR_ENSEMBLE) +ENSEMBLE_CHECK = 'ensemble check' + +SELECT_SAVED_ENSEMBLE = 'Select Saved Ensemble' +SELECT_SAVED_SETTING = 'Select Saved Setting' +ENSEMBLE_OPTION = "Ensemble Customization Options" +MDX_OPTION = "Advanced MDX-Net Options" +DEMUCS_OPTION = "Advanced Demucs Options" +VR_OPTION = "Advanced VR Options" +HELP_OPTION = "Open Information Guide" +ERROR_OPTION = "Open Error Log" +VERIFY_BEGIN = 'Verifying file ' +SAMPLE_BEGIN = 'Creating Sample ' +MODEL_MISSING_CHECK = 'Model Missing:' + +# Audio Player + +PLAYING_SONG = ": Playing" +PAUSE_SONG = ": Paused" +STOP_SONG = ": Stopped" + +SELECTED_VER = 'Selected' +DETECTED_VER = 'Detected' + +SAMPLE_MODE_CHECKBOX = lambda v:f'Sample Mode ({v}s)' +REMOVED_FILES = lambda r, e:f'Audio Input Verification Report:\n\nRemoved Files:\n\n{r}\n\nError Details:\n\n{e}' +ADVANCED_SETTINGS = (ENSEMBLE_OPTION, MDX_OPTION, DEMUCS_OPTION, VR_OPTION, HELP_OPTION, ERROR_OPTION) + +WAV = 'WAV' +FLAC = 'FLAC' +MP3 = 'MP3' + +MP3_BIT_RATES = ('96k', '128k', '160k', '224k', '256k', '320k') +WAV_TYPE = ('PCM_U8', 'PCM_16', 'PCM_24', 'PCM_32', '32-bit Float', '64-bit Float') + +SELECT_SAVED_SET = 'Choose Option' +SAVE_SETTINGS = 'Save Current Settings' +RESET_TO_DEFAULT = 'Reset to Default' +RESET_FULL_TO_DEFAULT = 'Reset to Default' +RESET_PM_TO_DEFAULT = 'Reset All Application Settings to Default' + +SAVE_SET_OPTIONS = (SAVE_SETTINGS, RESET_TO_DEFAULT) + +TIME_PITCH = ('1.0', '2.0', '3.0', '4.0') +TIME_TEXT = '_time_stretched' +PITCH_TEXT = '_pitch_shifted' + +#RegEx Input Validation + +REG_PITCH = r'^[-+]?(1[0]|[0-9]([.][0-9]*)?)$' +REG_TIME = r'^[+]?(1[0]|[0-9]([.][0-9]*)?)$' +REG_COMPENSATION = r'\b^(1[0]|[0-9]([.][0-9]*)?|Auto|None)$\b' +REG_THES_POSTPORCESS = r'\b^([0]([.][0-9]{0,6})?)$\b' +REG_CHUNKS = r'\b^(200|1[0-9][0-9]|[1-9][0-9]?|Auto|Full)$\b' +REG_CHUNKS_DEMUCS = r'\b^(200|1[0-9][0-9]|[1-9][0-9]?|Auto|Full)$\b' +REG_MARGIN = r'\b^[0-9]*$\b' +REG_SEGMENTS = r'\b^(200|1[0-9][0-9]|[1-9][0-9]?|Default)$\b' +REG_SAVE_INPUT = r'\b^([a-zA-Z0-9 -]{0,25})$\b' +REG_AGGRESSION = r'^[-+]?[0-9]\d*?$' +REG_WINDOW = r'\b^[0-9]{0,4}$\b' +REG_SHIFTS = r'\b^[0-9]*$\b' +REG_BATCHES = r'\b^([0-9]*?|Default)$\b' +REG_OVERLAP = r'\b^([0]([.][0-9]{0,6})?|None)$\b' + +# Sub Menu + +VR_ARCH_SETTING_LOAD = 'Load for VR Arch' +MDX_SETTING_LOAD = 'Load for MDX-Net' +DEMUCS_SETTING_LOAD = 'Load for Demucs' +ALL_ARCH_SETTING_LOAD = 'Load for Full Application' + +# Mappers + +DEFAULT_DATA = { + + 'chosen_process_method': MDX_ARCH_TYPE, + 'vr_model': CHOOSE_MODEL, + 'aggression_setting': 10, + 'window_size': 512, + 'batch_size': 4, + 'crop_size': 256, + 'is_tta': False, + 'is_output_image': False, + 'is_post_process': False, + 'is_high_end_process': False, + 'post_process_threshold': 0.2, + 'vr_voc_inst_secondary_model': NO_MODEL, + 'vr_other_secondary_model': NO_MODEL, + 'vr_bass_secondary_model': NO_MODEL, + 'vr_drums_secondary_model': NO_MODEL, + 'vr_is_secondary_model_activate': False, + 'vr_voc_inst_secondary_model_scale': 0.9, + 'vr_other_secondary_model_scale': 0.7, + 'vr_bass_secondary_model_scale': 0.5, + 'vr_drums_secondary_model_scale': 0.5, + 'demucs_model': CHOOSE_MODEL, + 'demucs_stems': ALL_STEMS, + 'segment': DEMUCS_SEGMENTS[0], + 'overlap': DEMUCS_OVERLAP[0], + 'shifts': 2, + 'chunks_demucs': CHUNKS[0], + 'margin_demucs': 44100, + 'is_chunk_demucs': False, + 'is_chunk_mdxnet': False, + 'is_primary_stem_only_Demucs': False, + 'is_secondary_stem_only_Demucs': False, + 'is_split_mode': True, + 'is_demucs_combine_stems': True, + 'demucs_voc_inst_secondary_model': NO_MODEL, + 'demucs_other_secondary_model': NO_MODEL, + 'demucs_bass_secondary_model': NO_MODEL, + 'demucs_drums_secondary_model': NO_MODEL, + 'demucs_is_secondary_model_activate': False, + 'demucs_voc_inst_secondary_model_scale': 0.9, + 'demucs_other_secondary_model_scale': 0.7, + 'demucs_bass_secondary_model_scale': 0.5, + 'demucs_drums_secondary_model_scale': 0.5, + 'demucs_stems': ALL_STEMS, + 'demucs_pre_proc_model': NO_MODEL, + 'is_demucs_pre_proc_model_activate': False, + 'is_demucs_pre_proc_model_inst_mix': False, + 'mdx_net_model': CHOOSE_MODEL, + 'chunks': CHUNKS[0], + 'margin': 44100, + 'compensate': AUTO_SELECT, + 'is_denoise': False, + 'is_invert_spec': False, + 'is_mixer_mode': False, + 'mdx_batch_size': DEF_OPT, + 'mdx_voc_inst_secondary_model': NO_MODEL, + 'mdx_other_secondary_model': NO_MODEL, + 'mdx_bass_secondary_model': NO_MODEL, + 'mdx_drums_secondary_model': NO_MODEL, + 'mdx_is_secondary_model_activate': False, + 'mdx_voc_inst_secondary_model_scale': 0.9, + 'mdx_other_secondary_model_scale': 0.7, + 'mdx_bass_secondary_model_scale': 0.5, + 'mdx_drums_secondary_model_scale': 0.5, + 'is_save_all_outputs_ensemble': True, + 'is_append_ensemble_name': False, + 'chosen_audio_tool': AUDIO_TOOL_OPTIONS[0], + 'choose_algorithm': MANUAL_ENSEMBLE_OPTIONS[0], + 'time_stretch_rate': 2.0, + 'pitch_rate': 2.0, + 'is_gpu_conversion': False, + 'is_primary_stem_only': False, + 'is_secondary_stem_only': False, + 'is_testing_audio': False, + 'is_add_model_name': False, + 'is_accept_any_input': False, + 'is_task_complete': False, + 'is_normalization': False, + 'is_create_model_folder': False, + 'mp3_bit_set': '320k', + 'save_format': WAV, + 'wav_type_set': 'PCM_16', + 'user_code': '', + 'export_path': '', + 'input_paths': [], + 'lastDir': None, + 'export_path': '', + 'model_hash_table': None, + 'help_hints_var': False, + 'model_sample_mode': False, + 'model_sample_mode_duration': 30 +} + +SETTING_CHECK = ('vr_model', + 'aggression_setting', + 'window_size', + 'batch_size', + 'crop_size', + 'is_tta', + 'is_output_image', + 'is_post_process', + 'is_high_end_process', + 'post_process_threshold', + 'vr_voc_inst_secondary_model', + 'vr_other_secondary_model', + 'vr_bass_secondary_model', + 'vr_drums_secondary_model', + 'vr_is_secondary_model_activate', + 'vr_voc_inst_secondary_model_scale', + 'vr_other_secondary_model_scale', + 'vr_bass_secondary_model_scale', + 'vr_drums_secondary_model_scale', + 'demucs_model', + 'segment', + 'overlap', + 'shifts', + 'chunks_demucs', + 'margin_demucs', + 'is_chunk_demucs', + 'is_primary_stem_only_Demucs', + 'is_secondary_stem_only_Demucs', + 'is_split_mode', + 'is_demucs_combine_stems', + 'demucs_voc_inst_secondary_model', + 'demucs_other_secondary_model', + 'demucs_bass_secondary_model', + 'demucs_drums_secondary_model', + 'demucs_is_secondary_model_activate', + 'demucs_voc_inst_secondary_model_scale', + 'demucs_other_secondary_model_scale', + 'demucs_bass_secondary_model_scale', + 'demucs_drums_secondary_model_scale', + 'demucs_stems', + 'mdx_net_model', + 'chunks', + 'margin', + 'compensate', + 'is_denoise', + 'is_invert_spec', + 'mdx_batch_size', + 'mdx_voc_inst_secondary_model', + 'mdx_other_secondary_model', + 'mdx_bass_secondary_model', + 'mdx_drums_secondary_model', + 'mdx_is_secondary_model_activate', + 'mdx_voc_inst_secondary_model_scale', + 'mdx_other_secondary_model_scale', + 'mdx_bass_secondary_model_scale', + 'mdx_drums_secondary_model_scale', + 'is_save_all_outputs_ensemble', + 'is_append_ensemble_name', + 'chosen_audio_tool', + 'choose_algorithm', + 'time_stretch_rate', + 'pitch_rate', + 'is_primary_stem_only', + 'is_secondary_stem_only', + 'is_testing_audio', + 'is_add_model_name', + "is_accept_any_input", + 'is_task_complete', + 'is_create_model_folder', + 'mp3_bit_set', + 'save_format', + 'wav_type_set', + 'user_code', + 'is_gpu_conversion', + 'is_normalization', + 'help_hints_var', + 'model_sample_mode', + 'model_sample_mode_duration') + +# Message Box Text + +INVALID_INPUT = 'Invalid Input', 'The input is invalid.\n\nPlease verify the input still exists or is valid and try again.' +INVALID_EXPORT = 'Invalid Export Directory', 'You have selected an invalid export directory.\n\nPlease make sure the selected directory still exists.' +INVALID_ENSEMBLE = 'Not Enough Models', 'You must select 2 or more models to run ensemble.' +INVALID_MODEL = 'No Model Chosen', 'You must select an model to continue.' +MISSING_MODEL = 'Model Missing', 'The selected model is missing or not valid.' +ERROR_OCCURED = 'Error Occured', '\n\nWould you like to open the error log for more details?\n' + +# GUI Text Constants + +BACK_TO_MAIN_MENU = 'Back to Main Menu' + +# Help Hint Text + +INTERNAL_MODEL_ATT = 'Internal model attribute. \n\n ***Do not change this setting if you are unsure!***' +STOP_HELP = 'Halts any running processes. \n A pop-up window will ask the user to confirm the action.' +SETTINGS_HELP = 'Opens the main settings guide. This window includes the \"Download Center\"' +COMMAND_TEXT_HELP = 'Provides information on the progress of the current process.' +SAVE_CURRENT_SETTINGS_HELP = 'Allows the user to open any saved settings or save the current application settings.' +CHUNKS_HELP = ('For MDX-Net, all values use the same amount of resources. Using chunks is no longer recommended.\n\n' + \ + '• This option is now only for output quality.\n' + \ + '• Some tracks may fare better depending on the value.\n' + \ + '• Some tracks may fare worse depending on the value.\n' + \ + '• Larger chunk sizes use will take less time to process.\n' +\ + '• Smaller chunk sizes use will take more time to process.\n') +CHUNKS_DEMUCS_HELP = ('This option allows the user to reduce (or increase) RAM or V-RAM usage.\n\n' + \ + '• Smaller chunk sizes use less RAM or V-RAM but can also increase processing times.\n' + \ + '• Larger chunk sizes use more RAM or V-RAM but can also reduce processing times.\n' + \ + '• Selecting \"Auto\" calculates an appropriate chuck size based on how much RAM or V-RAM your system has.\n' + \ + '• Selecting \"Full\" will process the track as one whole chunk. (not recommended)\n' + \ + '• The default selection is \"Auto\".') +MARGIN_HELP = 'Selects the frequency margins to slice the chunks from.\n\n• The recommended margin size is 44100.\n• Other values can give unpredictable results.' +AGGRESSION_SETTING_HELP = ('This option allows you to set how strong the primary stem extraction will be.\n\n' + \ + '• The range is 0-100.\n' + \ + '• Higher values perform deeper extractions.\n' + \ + '• The default is 10 for instrumental & vocal models.\n' + \ + '• Values over 10 can result in muddy-sounding instrumentals for the non-vocal models') +WINDOW_SIZE_HELP = ('The smaller your window size, the better your conversions will be. \nHowever, a smaller window means longer conversion times and heavier resource usage.\n\n' + \ + 'Breakdown of the selectable window size values:\n' + \ + '• 1024 - Low conversion quality, shortest conversion time, low resource usage.\n' + \ + '• 512 - Average conversion quality, average conversion time, normal resource usage.\n' + \ + '• 320 - Better conversion quality.') +DEMUCS_STEMS_HELP = ('Here, you can choose which stem to extract using the selected model.\n\n' +\ + 'Stem Selections:\n\n' +\ + '• All Stems - Saves all of the stems the model is able to extract.\n' +\ + '• Vocals - Pulls vocal stem only.\n' +\ + '• Other - Pulls other stem only.\n' +\ + '• Bass - Pulls bass stem only.\n' +\ + '• Drums - Pulls drum stem only.\n') +SEGMENT_HELP = ('This option allows the user to reduce (or increase) RAM or V-RAM usage.\n\n' + \ + '• Smaller segment sizes use less RAM or V-RAM but can also increase processing times.\n' + \ + '• Larger segment sizes use more RAM or V-RAM but can also reduce processing times.\n' + \ + '• Selecting \"Default\" uses the recommended segment size.\n' + \ + '• It is recommended that you not use segments with \"Chunking\".') +ENSEMBLE_MAIN_STEM_HELP = 'Allows the user to select the type of stems they wish to ensemble.\n\nOptions:\n\n' +\ + f'• {VOCAL_PAIR} - The primary stem will be the vocals and the secondary stem will be the the instrumental\n' +\ + f'• {OTHER_PAIR} - The primary stem will be other and the secondary stem will be no other (the mixture without the \'other\' stem)\n' +\ + f'• {BASS_PAIR} - The primary stem will be bass and the secondary stem will be no bass (the mixture without the \'bass\' stem)\n' +\ + f'• {DRUM_PAIR} - The primary stem will be drums and the secondary stem will be no drums (the mixture without the \'drums\' stem)\n' +\ + f'• {FOUR_STEM_ENSEMBLE} - This option will gather all the 4 stem Demucs models and ensemble all of the outputs.\n' +ENSEMBLE_TYPE_HELP = 'Allows the user to select the ensemble algorithm to be used to generate the final output.\n\nExample & Other Note:\n\n' +\ + f'• {MAX_MIN} - If this option is chosen, the primary stem outputs will be processed through \nthe \'Max Spec\' algorithm, and the secondary stem will be processed through the \'Min Spec\' algorithm.\n' +\ + f'• Only a single algorithm will be shown when the \'4 Stem Ensemble\' option is chosen.\n\nAlgorithm Details:\n\n' +\ + f'• {MAX_SPEC} - This algorithm combines the final results and generates the highest possible output from them.\nFor example, if this algorithm were processing vocal stems, you would get the fullest possible \n' +\ + 'result making the ensembled vocal stem sound cleaner. However, it might result in more unwanted artifacts.\n' +\ + f'• {MIN_SPEC} - This algorithm combines the results and generates the lowest possible output from them.\nFor example, if this algorithm were processing instrumental stems, you would get the cleanest possible result \n' +\ + 'result, eliminating more unwanted artifacts. However, the result might also sound \'muddy\' and lack a fuller sound.\n' +\ + f'• {AUDIO_AVERAGE} - This algorithm simply combines the results and averages all of them together. \n' +ENSEMBLE_LISTBOX_HELP = 'List of the all the models available for the main stem pair selected.' +IS_GPU_CONVERSION_HELP = ('When checked, the application will attempt to use your GPU (if you have one).\n' +\ + 'If you do not have a GPU but have this checked, the application will default to your CPU.\n\n' +\ + 'Note: CPU conversions are much slower than those processed through the GPU.') +SAVE_STEM_ONLY_HELP = 'Allows the user to save only the selected stem.' +IS_NORMALIZATION_HELP = 'Normalizes output to prevent clipping.' +CROP_SIZE_HELP = '**Only compatible with select models only!**\n\n Setting should match training crop-size value. Leave as is if unsure.' +IS_TTA_HELP = ('This option performs Test-Time-Augmentation to improve the separation quality.\n\n' +\ + 'Note: Having this selected will increase the time it takes to complete a conversion') +IS_POST_PROCESS_HELP = ('This option can potentially identify leftover instrumental artifacts within the vocal outputs. \nThis option may improve the separation of some songs.\n\n' +\ + 'Note: Selecting this option can adversely affect the conversion process, depending on the track. Because of this, it is only recommended as a last resort.') +IS_HIGH_END_PROCESS_HELP = 'The application will mirror the missing frequency range of the output.' +SHIFTS_HELP = ('Performs multiple predictions with random shifts of the input and averages them.\n\n' +\ + '• The higher number of shifts, the longer the prediction will take. \n- Not recommended unless you have a GPU.') +OVERLAP_HELP = 'This option controls the amount of overlap between prediction windows (for Demucs one window is 10 seconds)' +IS_CHUNK_DEMUCS_HELP = '• Enables \"Chunks\".\n• We recommend you not enable this option with \"Split Mode\" enabled or with the Demucs v4 Models.' +IS_CHUNK_MDX_NET_HELP = '• Enables \"Chunks\".\n• Using this option for MDX-Net no longer effects RAM usage.\n• Having this enabled will effect output quality, for better or worse depending on the set value.' +IS_SPLIT_MODE_HELP = ('• Enables \"Segments\". \n• We recommend you not enable this option with \"Enable Chunks\".\n' +\ + '• Deselecting this option is only recommended for those with powerful PCs or if using \"Chunk\" mode instead.') +IS_DEMUCS_COMBINE_STEMS_HELP = 'The application will create the secondary stem by combining the remaining stems \ninstead of inverting the primary stem with the mixture.' +COMPENSATE_HELP = 'Compensates the audio of the primary stems to allow for a better secondary stem.' +IS_DENOISE_HELP = '• This option removes a majority of the noise generated by the MDX-Net models.\n• The conversion will take nearly twice as long with this enabled.' +CLEAR_CACHE_HELP = 'Clears any user selected model settings for previously unrecognized models.' +IS_SAVE_ALL_OUTPUTS_ENSEMBLE_HELP = 'Enabling this option will keep all indivudual outputs generated by an ensemble.' +IS_APPEND_ENSEMBLE_NAME_HELP = 'The application will append the ensemble name to the final output \nwhen this option is enabled.' +DONATE_HELP = 'Takes the user to an external web-site to donate to this project!' +IS_INVERT_SPEC_HELP = '• This option may produce a better secondary stem.\n• Inverts primary stem with mixture using spectragrams instead of wavforms.\n• This inversion method is slightly slower.' +IS_MIXER_MODE_HELP = '• This option may improve separations for outputs from 4-stem models.\n• Might produce more noise.\n• This option might slow down separation time.' +IS_TESTING_AUDIO_HELP = 'Appends a unique 10 digit number to output files so the user \ncan compare results with different settings.' +IS_MODEL_TESTING_AUDIO_HELP = 'Appends the model name to output files so the user \ncan compare results with different settings.' +IS_ACCEPT_ANY_INPUT_HELP = 'The application will accept any input when enabled, even if it does not have an audio format extension.\n\nThis is for experimental purposes, and having it enabled is not recommended.' +IS_TASK_COMPLETE_HELP = 'When enabled, chimes will be heard when a process completes or fails.' +IS_CREATE_MODEL_FOLDER_HELP = 'Two new directories will be generated for the outputs in \nthe export directory after each conversion.\n\n' +\ + '• First directory - Named after the model.\n' +\ + '• Second directory - Named after the track.\n\n' +\ + '• Example: \n\n' +\ + '─ Export Directory\n' +\ + ' └── First Directory\n' +\ + ' └── Second Directory\n' +\ + ' └── Output File(s)' +DELETE_YOUR_SETTINGS_HELP = 'This menu contains your saved settings. You will be asked to \nconfirm if you wish to delete the selected setting.' +SET_STEM_NAME_HELP = 'Choose the primary stem for the selected model.' +MDX_DIM_T_SET_HELP = INTERNAL_MODEL_ATT +MDX_DIM_F_SET_HELP = INTERNAL_MODEL_ATT +MDX_N_FFT_SCALE_SET_HELP = 'Set the N_FFT size the model was trained with.' +POPUP_COMPENSATE_HELP = f'Choose the appropriate voluem compensattion for the selected model\n\nReminder: {COMPENSATE_HELP}' +VR_MODEL_PARAM_HELP = 'Choose the parameters needed to run the selected model.' +CHOSEN_ENSEMBLE_HELP = 'Select saved enselble or save current ensemble.\n\nDefault Selections:\n\n• Save the current ensemble.\n• Clears all current model selections.' +CHOSEN_PROCESS_METHOD_HELP = 'Here, you choose between different Al networks and algorithms to process your track.\n\n' +\ + 'There are five options:\n\n' +\ + '• VR Architecture - These models use magnitude spectrograms for Source Separation.\n' +\ + '• MDX-Net - These models use Hybrid Spectrogram/Waveform for Source Separation.\n' +\ + '• Demucs v3 - These models use Hybrid Spectrogram/Waveform for Source Separation.\n' +\ + '• Ensemble Mode - Here, you can get the best results from multiple models and networks.\n' +\ + '• Audio Tools - These are additional tools for added convenience.' +INPUT_FOLDER_ENTRY_HELP = 'Select Input:\n\nHere is where you select the audio files(s) you wish to process.' +INPUT_FOLDER_ENTRY_HELP_2 = 'Input Option Menu:\n\nClick here to access the input option menu.' +OUTPUT_FOLDER_ENTRY_HELP = 'Select Output:\n\nHere is where you select the directory where your processed files are to be saved.' +INPUT_FOLDER_BUTTON_HELP = 'Open Input Folder Button: \n\nOpens the directory containing the selected input audio file(s).' +OUTPUT_FOLDER_BUTTON_HELP = 'Open Output Folder Button: \n\nOpens the selected output folder.' +CHOOSE_MODEL_HELP = 'Each process method comes with its own set of options and models.\n\nHere is where you choose the model associated with the selected process method.' +FORMAT_SETTING_HELP = 'Save outputs as ' +SECONDARY_MODEL_ACTIVATE_HELP = 'When enabled, the application will run an additional inference with the selected model(s) above.' +SECONDARY_MODEL_HELP = 'Choose the secondary model associated with this stem you wish to run with the current process method.' +SECONDARY_MODEL_SCALE_HELP = 'The scale determines how the final audio outputs will be averaged between the primary and secondary models.\n\nFor example:\n\n' +\ + '• 10% - 10 percent of the main model result will be factored into the final result.\n' +\ + '• 50% - The results from the main and secondary models will be averaged evenly.\n' +\ + '• 90% - 90 percent of the main model result will be factored into the final result.' +PRE_PROC_MODEL_ACTIVATE_HELP = 'The application will run an inference with the selected model above, pulling only the instrumental stem when enabled. \nFrom there, all of the non-vocal stems will be pulled from the generated instrumental.\n\nNotes:\n\n' +\ + '• This option can significantly reduce vocal bleed within the non-vocal stems.\n' +\ + '• It is only available in Demucs.\n' +\ + '• It is only compatible with non-vocal and non-instrumental stem outputs.\n' +\ + '• This will increase thetotal processing time.\n' +\ + '• Only VR and MDX-Net Vocal or Instrumental models are selectable above.' + +AUDIO_TOOLS_HELP = 'Here, you choose between different audio tools to process your track.\n\n' +\ + '• Manual Ensemble - You must have 2 or more files selected as your inputs. Allows the user to run their tracks through \nthe same algorithms used in Ensemble Mode.\n' +\ + '• Align Inputs - You must have exactly 2 files selected as your inputs. The second input will be aligned with the first input.\n' +\ + '• Time Stretch - The user can speed up or slow down the selected inputs.\n' +\ + '• Change Pitch - The user can change the pitch for the selected inputs.\n' +PRE_PROC_MODEL_INST_MIX_HELP = 'When enabled, the application will generate a third output without the selected stem and vocals.' +MODEL_SAMPLE_MODE_HELP = 'Allows the user to process only part of a track to sample settings or a model without \nrunning a full conversion.\n\nNotes:\n\n' +\ + '• The number in the parentheses is the current number of seconds the generated sample will be.\n' +\ + '• You can choose the number of seconds to extract from the track in the \"Additional Settings\" menu.' + +POST_PROCESS_THREASHOLD_HELP = 'Allows the user to control the intensity of the Post_process option.\n\nNotes:\n\n' +\ + '• Higher values potentially remove more artifacts. However, bleed might increase.\n' +\ + '• Lower values limit artifact removal.' + +BATCH_SIZE_HELP = 'Specify the number of batches to be processed at a time.\n\nNotes:\n\n' +\ + '• Higher values mean more RAM usage but slightly faster processing times.\n' +\ + '• Lower values mean less RAM usage but slightly longer processing times.\n' +\ + '• Batch size value has no effect on output quality.' + +# Warning Messages + +STORAGE_ERROR = 'Insufficient Storage', 'There is not enough storage on main drive to continue. Your main drive must have at least 3 GB\'s of storage in order for this application function properly. \n\nPlease ensure your main drive has at least 3 GB\'s of storage and try again.\n\n' +STORAGE_WARNING = 'Available Storage Low', 'Your main drive is running low on storage. Your main drive must have at least 3 GB\'s of storage in order for this application function properly.\n\n' +CONFIRM_WARNING = '\nAre you sure you wish to continue?' +PROCESS_FAILED = 'Process failed, please see error log\n' +EXIT_PROCESS_ERROR = 'Active Process', 'Please stop the active process or wait for it to complete before you exit.' +EXIT_HALTED_PROCESS_ERROR = 'Halting Process', 'Please wait for the application to finish halting the process before exiting.' +EXIT_DOWNLOAD_ERROR = 'Active Download', 'Please stop the download or wait for it to complete before you exit.' +SET_TO_DEFAULT_PROCESS_ERROR = 'Active Process', 'You cannot reset all of the application settings during an active process.' +SET_TO_ANY_PROCESS_ERROR = 'Active Process', 'You cannot reset the application settings during an active process.' +RESET_ALL_TO_DEFAULT_WARNING = 'Reset Settings Confirmation', 'All application settings will be set to factory default.\n\nAre you sure you wish to continue?' +AUDIO_VERIFICATION_CHECK = lambda i, e:f'++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nBroken File Removed: \n\n{i}\n\nError Details:\n\n{e}\n++++++++++++++++++++++++++++++++++++++++++++++++++++' +INVALID_ONNX_MODEL_ERROR = 'Invalid Model', 'The file selected is not a valid MDX-Net model. Please see the error log for more information.' + + +# Separation Text + +LOADING_MODEL = 'Loading model...' +INFERENCE_STEP_1 = 'Running inference...' +INFERENCE_STEP_1_SEC = 'Running inference (secondary model)...' +INFERENCE_STEP_1_4_STEM = lambda stem:f'Running inference (secondary model for {stem})...' +INFERENCE_STEP_1_PRE = 'Running inference (pre-process model)...' +INFERENCE_STEP_2_PRE = lambda pm, m:f'Loading pre-process model ({pm}: {m})...' +INFERENCE_STEP_2_SEC = lambda pm, m:f'Loading secondary model ({pm}: {m})...' +INFERENCE_STEP_2_SEC_CACHED_MODOEL = lambda pm, m:f'Secondary model ({pm}: {m}) cache loaded.\n' +INFERENCE_STEP_2_PRE_CACHED_MODOEL = lambda pm, m:f'Pre-process model ({pm}: {m}) cache loaded.\n' +INFERENCE_STEP_2_SEC_CACHED = 'Loading cached secondary model source(s)... Done!\n' +INFERENCE_STEP_2_PRIMARY_CACHED = 'Model cache loaded.\n' +INFERENCE_STEP_2 = 'Inference complete.' +SAVING_STEM = 'Saving ', ' stem...' +SAVING_ALL_STEMS = 'Saving all stems...' +ENSEMBLING_OUTPUTS = 'Ensembling outputs...' +DONE = ' Done!\n' +ENSEMBLES_SAVED = 'Ensembled outputs saved!\n\n' +NEW_LINES = "\n\n" +NEW_LINE = "\n" +NO_LINE = '' + +# Widget Placements + +MAIN_ROW_Y = -15, -17 +MAIN_ROW_X = -4, 21 +MAIN_ROW_WIDTH = -53 +MAIN_ROW_2_Y = -15, -17 +MAIN_ROW_2_X = -28, 1 +CHECK_BOX_Y = 0 +CHECK_BOX_X = 20 +CHECK_BOX_WIDTH = -50 +CHECK_BOX_HEIGHT = 2 +LEFT_ROW_WIDTH = -10 +LABEL_HEIGHT = -5 +OPTION_HEIGHT = 7 +LOW_MENU_Y = 18, 16 +FFMPEG_EXT = (".aac", ".aiff", ".alac" ,".flac", ".FLAC", ".mov", ".mp4", ".MP4", + ".m4a", ".M4A", ".mp2", ".mp3", "MP3", ".mpc", ".mpc8", + ".mpeg", ".ogg", ".OGG", ".tta", ".wav", ".wave", ".WAV", ".WAVE", ".wma", ".webm", ".eac3", ".mkv") + +FFMPEG_MORE_EXT = (".aa", ".aac", ".ac3", ".aiff", ".alac", ".avi", ".f4v",".flac", ".flic", ".flv", + ".m4v",".mlv", ".mov", ".mp4", ".m4a", ".mp2", ".mp3", ".mp4", ".mpc", ".mpc8", + ".mpeg", ".ogg", ".tta", ".tty", ".vcd", ".wav", ".wma") +ANY_EXT = "" + +# Secondary Menu Constants + +VOCAL_PAIR_PLACEMENT = 1, 2, 3, 4 +OTHER_PAIR_PLACEMENT = 5, 6, 7, 8 +BASS_PAIR_PLACEMENT = 9, 10, 11, 12 +DRUMS_PAIR_PLACEMENT = 13, 14, 15, 16 + +# Drag n Drop String Checks + +DOUBLE_BRACKET = "} {" +RIGHT_BRACKET = "}" +LEFT_BRACKET = "{" + +# Manual Downloads + +VR_PLACEMENT_TEXT = 'Place models in \"models/VR_Models\" directory.' +MDX_PLACEMENT_TEXT = 'Place models in \"models/MDX_Net_Models\" directory.' +DEMUCS_PLACEMENT_TEXT = 'Place models in \"models/Demucs_Models\" directory.' +DEMUCS_V3_V4_PLACEMENT_TEXT = 'Place items in \"models/Demucs_Models/v3_v4_repo\" directory.' + +FULL_DOWNLOAD_LIST_VR = { + "VR Arch Single Model v5: 1_HP-UVR": "1_HP-UVR.pth", + "VR Arch Single Model v5: 2_HP-UVR": "2_HP-UVR.pth", + "VR Arch Single Model v5: 3_HP-Vocal-UVR": "3_HP-Vocal-UVR.pth", + "VR Arch Single Model v5: 4_HP-Vocal-UVR": "4_HP-Vocal-UVR.pth", + "VR Arch Single Model v5: 5_HP-Karaoke-UVR": "5_HP-Karaoke-UVR.pth", + "VR Arch Single Model v5: 6_HP-Karaoke-UVR": "6_HP-Karaoke-UVR.pth", + "VR Arch Single Model v5: 7_HP2-UVR": "7_HP2-UVR.pth", + "VR Arch Single Model v5: 8_HP2-UVR": "8_HP2-UVR.pth", + "VR Arch Single Model v5: 9_HP2-UVR": "9_HP2-UVR.pth", + "VR Arch Single Model v5: 10_SP-UVR-2B-32000-1": "10_SP-UVR-2B-32000-1.pth", + "VR Arch Single Model v5: 11_SP-UVR-2B-32000-2": "11_SP-UVR-2B-32000-2.pth", + "VR Arch Single Model v5: 12_SP-UVR-3B-44100": "12_SP-UVR-3B-44100.pth", + "VR Arch Single Model v5: 13_SP-UVR-4B-44100-1": "13_SP-UVR-4B-44100-1.pth", + "VR Arch Single Model v5: 14_SP-UVR-4B-44100-2": "14_SP-UVR-4B-44100-2.pth", + "VR Arch Single Model v5: 15_SP-UVR-MID-44100-1": "15_SP-UVR-MID-44100-1.pth", + "VR Arch Single Model v5: 16_SP-UVR-MID-44100-2": "16_SP-UVR-MID-44100-2.pth", + "VR Arch Single Model v4: MGM_HIGHEND_v4": "MGM_HIGHEND_v4.pth", + "VR Arch Single Model v4: MGM_LOWEND_A_v4": "MGM_LOWEND_A_v4.pth", + "VR Arch Single Model v4: MGM_LOWEND_B_v4": "MGM_LOWEND_B_v4.pth", + "VR Arch Single Model v4: MGM_MAIN_v4": "MGM_MAIN_v4.pth" + } + +FULL_DOWNLOAD_LIST_MDX = { + "MDX-Net Model: UVR-MDX-NET Main": "UVR_MDXNET_Main.onnx", + "MDX-Net Model: UVR-MDX-NET Inst Main": "UVR-MDX-NET-Inst_Main.onnx", + "MDX-Net Model: UVR-MDX-NET 1": "UVR_MDXNET_1_9703.onnx", + "MDX-Net Model: UVR-MDX-NET 2": "UVR_MDXNET_2_9682.onnx", + "MDX-Net Model: UVR-MDX-NET 3": "UVR_MDXNET_3_9662.onnx", + "MDX-Net Model: UVR-MDX-NET Inst 1": "UVR-MDX-NET-Inst_1.onnx", + "MDX-Net Model: UVR-MDX-NET Inst 2": "UVR-MDX-NET-Inst_2.onnx", + "MDX-Net Model: UVR-MDX-NET Inst 3": "UVR-MDX-NET-Inst_3.onnx", + "MDX-Net Model: UVR-MDX-NET Karaoke": "UVR_MDXNET_KARA.onnx", + "MDX-Net Model: UVR_MDXNET_9482": "UVR_MDXNET_9482.onnx", + "MDX-Net Model: Kim_Vocal_1": "Kim_Vocal_1.onnx", + "MDX-Net Model: kuielab_a_vocals": "kuielab_a_vocals.onnx", + "MDX-Net Model: kuielab_a_other": "kuielab_a_other.onnx", + "MDX-Net Model: kuielab_a_bass": "kuielab_a_bass.onnx", + "MDX-Net Model: kuielab_a_drums": "kuielab_a_drums.onnx", + "MDX-Net Model: kuielab_b_vocals": "kuielab_b_vocals.onnx", + "MDX-Net Model: kuielab_b_other": "kuielab_b_other.onnx", + "MDX-Net Model: kuielab_b_bass": "kuielab_b_bass.onnx", + "MDX-Net Model: kuielab_b_drums": "kuielab_b_drums.onnx"} + +FULL_DOWNLOAD_LIST_DEMUCS = { + + "Demucs v4: htdemucs_ft":{ + "f7e0c4bc-ba3fe64a.th":"https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/f7e0c4bc-ba3fe64a.th", + "d12395a8-e57c48e6.th":"https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/d12395a8-e57c48e6.th", + "92cfc3b6-ef3bcb9c.th":"https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/92cfc3b6-ef3bcb9c.th", + "04573f0d-f3cf25b2.th":"https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/04573f0d-f3cf25b2.th", + "htdemucs_ft.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/htdemucs_ft.yaml" + }, + + "Demucs v4: htdemucs":{ + "955717e8-8726e21a.th": "https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/955717e8-8726e21a.th", + "htdemucs.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/htdemucs.yaml" + }, + + "Demucs v4: hdemucs_mmi":{ + "75fc33f5-1941ce65.th": "https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/75fc33f5-1941ce65.th", + "hdemucs_mmi.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/hdemucs_mmi.yaml" + }, + "Demucs v4: htdemucs_6s":{ + "5c90dfd2-34c22ccb.th": "https://dl.fbaipublicfiles.com/demucs/hybrid_transformer/5c90dfd2-34c22ccb.th", + "htdemucs_6s.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/htdemucs_6s.yaml" + }, + "Demucs v3: mdx":{ + "0d19c1c6-0f06f20e.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/0d19c1c6-0f06f20e.th", + "7ecf8ec1-70f50cc9.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/7ecf8ec1-70f50cc9.th", + "c511e2ab-fe698775.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/c511e2ab-fe698775.th", + "7d865c68-3d5dd56b.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/7d865c68-3d5dd56b.th", + "mdx.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/mdx.yaml" + }, + + "Demucs v3: mdx_q":{ + "6b9c2ca1-3fd82607.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/6b9c2ca1-3fd82607.th", + "b72baf4e-8778635e.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/b72baf4e-8778635e.th", + "42e558d4-196e0e1b.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/42e558d4-196e0e1b.th", + "305bc58f-18378783.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/305bc58f-18378783.th", + "mdx_q.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/mdx_q.yaml" + }, + + "Demucs v3: mdx_extra":{ + "e51eebcc-c1b80bdd.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/e51eebcc-c1b80bdd.th", + "a1d90b5c-ae9d2452.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/a1d90b5c-ae9d2452.th", + "5d2d6c55-db83574e.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/5d2d6c55-db83574e.th", + "cfa93e08-61801ae1.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/cfa93e08-61801ae1.th", + "mdx_extra.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/mdx_extra.yaml" + }, + + "Demucs v3: mdx_extra_q": { + "83fc094f-4a16d450.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/83fc094f-4a16d450.th", + "464b36d7-e5a9386e.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/464b36d7-e5a9386e.th", + "14fc6a69-a89dd0ee.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/14fc6a69-a89dd0ee.th", + "7fd6ef75-a905dd85.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/7fd6ef75-a905dd85.th", + "mdx_extra_q.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/mdx_extra_q.yaml" + }, + + "Demucs v3: UVR Model":{ + "ebf34a2db.th": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/ebf34a2db.th", + "UVR_Demucs_Model_1.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/UVR_Demucs_Model_1.yaml" + }, + + "Demucs v3: repro_mdx_a":{ + "9a6b4851-03af0aa6.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/9a6b4851-03af0aa6.th", + "1ef250f1-592467ce.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/1ef250f1-592467ce.th", + "fa0cb7f9-100d8bf4.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/fa0cb7f9-100d8bf4.th", + "902315c2-b39ce9c9.th": "https://dl.fbaipublicfiles.com/demucs/mdx_final/902315c2-b39ce9c9.th", + "repro_mdx_a.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/repro_mdx_a.yaml" + }, + + "Demucs v3: repro_mdx_a_time_only":{ + "9a6b4851-03af0aa6.th":"https://dl.fbaipublicfiles.com/demucs/mdx_final/9a6b4851-03af0aa6.th", + "1ef250f1-592467ce.th":"https://dl.fbaipublicfiles.com/demucs/mdx_final/1ef250f1-592467ce.th", + "repro_mdx_a_time_only.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/repro_mdx_a_time_only.yaml" + }, + + "Demucs v3: repro_mdx_a_hybrid_only":{ + "fa0cb7f9-100d8bf4.th":"https://dl.fbaipublicfiles.com/demucs/mdx_final/fa0cb7f9-100d8bf4.th", + "902315c2-b39ce9c9.th":"https://dl.fbaipublicfiles.com/demucs/mdx_final/902315c2-b39ce9c9.th", + "repro_mdx_a_hybrid_only.yaml": "https://github.com/TRvlvr/model_repo/releases/download/all_public_uvr_models/repro_mdx_a_hybrid_only.yaml" + }, + + "Demucs v2: demucs": { + "demucs-e07c671f.th": "https://dl.fbaipublicfiles.com/demucs/v3.0/demucs-e07c671f.th" + }, + + "Demucs v2: demucs_extra": { + "demucs_extra-3646af93.th":"https://dl.fbaipublicfiles.com/demucs/v3.0/demucs_extra-3646af93.th" + }, + + "Demucs v2: demucs48_hq": { + "demucs48_hq-28a1282c.th":"https://dl.fbaipublicfiles.com/demucs/v3.0/demucs48_hq-28a1282c.th" + }, + + "Demucs v2: tasnet": { + "tasnet-beb46fac.th":"https://dl.fbaipublicfiles.com/demucs/v3.0/tasnet-beb46fac.th" + }, + + "Demucs v2: tasnet_extra": { + "tasnet_extra-df3777b2.th":"https://dl.fbaipublicfiles.com/demucs/v3.0/tasnet_extra-df3777b2.th" + }, + + "Demucs v2: demucs_unittest": { + "demucs_unittest-09ebc15f.th":"https://dl.fbaipublicfiles.com/demucs/v3.0/demucs_unittest-09ebc15f.th" + }, + + "Demucs v1: demucs": { + "demucs.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/demucs.th" + }, + + "Demucs v1: demucs_extra": { + "demucs_extra.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/demucs_extra.th" + }, + + "Demucs v1: light": { + "light.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/light.th" + }, + + "Demucs v1: light_extra": { + "light_extra.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/light_extra.th" + }, + + "Demucs v1: tasnet": { + "tasnet.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/tasnet.th" + }, + + "Demucs v1: tasnet_extra": { + "tasnet_extra.th":"https://dl.fbaipublicfiles.com/demucs/v2.0/tasnet_extra.th" + } + } + +# Main Menu Labels + +CHOOSE_PROC_METHOD_MAIN_LABEL = 'CHOOSE PROCESS METHOD' +SELECT_SAVED_SETTINGS_MAIN_LABEL = 'SELECT SAVED SETTINGS' +CHOOSE_MDX_MODEL_MAIN_LABEL = 'CHOOSE MDX-NET MODEL' +BATCHES_MDX_MAIN_LABEL = 'BATCH SIZE' +VOL_COMP_MDX_MAIN_LABEL = 'VOLUME COMPENSATION' +SELECT_VR_MODEL_MAIN_LABEL = 'CHOOSE VR MODEL' +AGGRESSION_SETTING_MAIN_LABEL = 'AGGRESSION SETTING' +WINDOW_SIZE_MAIN_LABEL = 'WINDOW SIZE' +CHOOSE_DEMUCS_MODEL_MAIN_LABEL = 'CHOOSE DEMUCS MODEL' +CHOOSE_DEMUCS_STEMS_MAIN_LABEL = 'CHOOSE STEM(S)' +CHOOSE_SEGMENT_MAIN_LABEL = 'SEGMENT' +ENSEMBLE_OPTIONS_MAIN_LABEL = 'ENSEMBLE OPTIONS' +CHOOSE_MAIN_PAIR_MAIN_LABEL = 'MAIN STEM PAIR' +CHOOSE_ENSEMBLE_ALGORITHM_MAIN_LABEL = 'ENSEMBLE ALGORITHM' +AVAILABLE_MODELS_MAIN_LABEL = 'AVAILABLE MODELS' +CHOOSE_AUDIO_TOOLS_MAIN_LABEL = 'CHOOSE AUDIO TOOL' +CHOOSE_MANUAL_ALGORITHM_MAIN_LABEL = 'CHOOSE ALGORITHM' +CHOOSE_RATE_MAIN_LABEL = 'RATE' +CHOOSE_SEMITONES_MAIN_LABEL = 'SEMITONES' +GPU_CONVERSION_MAIN_LABEL = 'GPU Conversion' + +if OPERATING_SYSTEM=="Darwin": + LICENSE_OS_SPECIFIC_TEXT = '• This application is intended for those running macOS Catalina and above.\n' +\ + '• Application functionality for systems running macOS Mojave or lower is not guaranteed.\n' +\ + '• Application functionality for older or budget Mac systems is not guaranteed.\n\n' + FONT_SIZE_F1 = 13 + FONT_SIZE_F2 = 11 + FONT_SIZE_F3 = 12 + FONT_SIZE_0 = 9 + FONT_SIZE_1 = 11 + FONT_SIZE_2 = 12 + FONT_SIZE_3 = 13 + FONT_SIZE_4 = 14 + FONT_SIZE_5 = 15 + FONT_SIZE_6 = 17 + HELP_HINT_CHECKBOX_WIDTH = 13 + MDX_CHECKBOXS_WIDTH = 14 + VR_CHECKBOXS_WIDTH = 14 + ENSEMBLE_CHECKBOXS_WIDTH = 18 + DEMUCS_CHECKBOXS_WIDTH = 14 + DEMUCS_PRE_CHECKBOXS_WIDTH = 20 + GEN_SETTINGS_WIDTH = 17 + MENU_COMBOBOX_WIDTH = 16 + +elif OPERATING_SYSTEM=="Linux": + LICENSE_OS_SPECIFIC_TEXT = '• This application is intended for those running Linux Ubuntu 18.04+.\n' +\ + '• Application functionality for systems running other Linux platforms is not guaranteed.\n' +\ + '• Application functionality for older or budget systems is not guaranteed.\n\n' + FONT_SIZE_F1 = 10 + FONT_SIZE_F2 = 8 + FONT_SIZE_F3 = 9 + FONT_SIZE_0 = 7 + FONT_SIZE_1 = 8 + FONT_SIZE_2 = 9 + FONT_SIZE_3 = 10 + FONT_SIZE_4 = 11 + FONT_SIZE_5 = 12 + FONT_SIZE_6 = 15 + HELP_HINT_CHECKBOX_WIDTH = 13 + MDX_CHECKBOXS_WIDTH = 14 + VR_CHECKBOXS_WIDTH = 16 + ENSEMBLE_CHECKBOXS_WIDTH = 25 + DEMUCS_CHECKBOXS_WIDTH = 18 + DEMUCS_PRE_CHECKBOXS_WIDTH = 27 + GEN_SETTINGS_WIDTH = 17 + MENU_COMBOBOX_WIDTH = 19 + +elif OPERATING_SYSTEM=="Windows": + LICENSE_OS_SPECIFIC_TEXT = '• This application is intended for those running Windows 10 or higher.\n' +\ + '• Application functionality for systems running Windows 7 or lower is not guaranteed.\n' +\ + '• Application functionality for Intel Pentium & Celeron CPUs systems is not guaranteed.\n\n' + FONT_SIZE_F1 = 10 + FONT_SIZE_F2 = 8 + FONT_SIZE_F3 = 9 + FONT_SIZE_0 = 7 + FONT_SIZE_1 = 8 + FONT_SIZE_2 = 9 + FONT_SIZE_3 = 10 + FONT_SIZE_4 = 11 + FONT_SIZE_5 = 12 + FONT_SIZE_6 = 15 + HELP_HINT_CHECKBOX_WIDTH = 16 + MDX_CHECKBOXS_WIDTH = 16 + VR_CHECKBOXS_WIDTH = 16 + ENSEMBLE_CHECKBOXS_WIDTH = 25 + DEMUCS_CHECKBOXS_WIDTH = 18 + DEMUCS_PRE_CHECKBOXS_WIDTH = 27 + GEN_SETTINGS_WIDTH = 23 + MENU_COMBOBOX_WIDTH = 19 + + +LICENSE_TEXT = lambda a, p:f'Current Application Version: Ultimate Vocal Remover {a}\n' +\ + f'Current Patch Version: {p}\n\n' +\ + 'Copyright (c) 2022 Ultimate Vocal Remover\n\n' +\ + 'UVR is free and open-source, but MIT licensed. Please credit us if you use our\n' +\ + f'models or code for projects unrelated to UVR.\n\n{LICENSE_OS_SPECIFIC_TEXT}' +\ + 'This bundle contains the UVR interface, Python, PyTorch, and other\n' +\ + 'dependencies needed to run the application effectively.\n\n' +\ + 'Website Links: This application, System or Service(s) may contain links to\n' +\ + 'other websites and downloads, and they are solely provided to you as an\n' +\ + 'additional convenience. You understand and acknowledge that by clicking\n' +\ + 'or activating such links you are accessing a site or service outside of\n' +\ + 'this application, and that we do not screen, review, approve, or otherwise\n' +\ + 'endorse any content or information contained in these linked websites.\n' +\ + 'You acknowledge and agree that we, our affiliates and partners are not\n' +\ + 'responsible for the contents of any of these linked websites, including\n' +\ + 'the accuracy or availability of information provided by the linked websites,\n' +\ + 'and we make no representations or warranties regarding your use of\n' +\ + 'the linked websites.\n\n' +\ + 'This application is MIT Licensed\n\n' +\ + 'Permission is hereby granted, free of charge, to any person obtaining a copy\n' +\ + 'of this software and associated documentation files (the "Software"), to deal\n' +\ + 'in the Software without restriction, including without limitation the rights\n' +\ + 'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' +\ + 'copies of the Software, and to permit persons to whom the Software is\n' +\ + 'furnished to do so, subject to the following conditions:\n\n' +\ + 'The above copyright notice and this permission notice shall be included in all\n' +\ + 'copies or substantial portions of the Software.\n\n' +\ + 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' +\ + 'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' +\ + 'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' +\ + 'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' +\ + 'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' +\ + 'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n' +\ + 'SOFTWARE.' + +CHANGE_LOG_HEADER = lambda patch:f"Patch Version:\n\n{patch}" + +#DND CONSTS + +MAC_DND_CHECK = ('/Users/', + '/Applications/', + '/Library/', + '/System/') +LINUX_DND_CHECK = ('/home/', + '/usr/') +WINDOWS_DND_CHECK = ('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:') + +WOOD_INST_MODEL_HASH = '0ec76fd9e65f81d8b4fbd13af4826ed8' +WOOD_INST_PARAMS = { + "vr_model_param": "4band_v3", + "primary_stem": NO_WIND_INST_STEM + } \ No newline at end of file diff --git a/gui_data/error_handling.py b/gui_data/error_handling.py new file mode 100644 index 0000000000000000000000000000000000000000..366d77d44420afe0cfa292dc879361b742bc6417 --- /dev/null +++ b/gui_data/error_handling.py @@ -0,0 +1,106 @@ +from datetime import datetime +import traceback + +CUDA_MEMORY_ERROR = "CUDA out of memory" +CUDA_RUNTIME_ERROR = "CUDNN error executing cudnnSetTensorNdDescriptor" +DEMUCS_MODEL_MISSING_ERROR = "is neither a single pre-trained model or a bag of models." +ENSEMBLE_MISSING_MODEL_ERROR = "local variable \'enseExport\' referenced before assignment" +FFMPEG_MISSING_ERROR = """audioread\__init__.py", line 116, in audio_open""" +FILE_MISSING_ERROR = "FileNotFoundError" +MDX_MEMORY_ERROR = "onnxruntime::CudaCall CUDA failure 2: out of memory" +MDX_MODEL_MISSING = "[ONNXRuntimeError] : 3 : NO_SUCHFILE" +MDX_MODEL_SETTINGS_ERROR = "Got invalid dimensions for input" +MDX_RUNTIME_ERROR = "onnxruntime::BFCArena::AllocateRawInternal" +MODULE_ERROR = "ModuleNotFoundError" +WINDOW_SIZE_ERROR = "h1_shape[3] must be greater than h2_shape[3]" +SF_WRITE_ERROR = "sf.write" +SYSTEM_MEMORY_ERROR = "DefaultCPUAllocator: not enough memory" +MISSING_MODEL_ERROR = "'NoneType\' object has no attribute \'model_basename\'" +ARRAY_SIZE_ERROR = "ValueError: \"array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.\"" +GPU_INCOMPATIBLE_ERROR = "no kernel image is available for execution on the device" + +CONTACT_DEV = 'If this error persists, please contact the developers with the error details.' + +ERROR_MAPPER = { + CUDA_MEMORY_ERROR: + ('The application was unable to allocate enough GPU memory to use this model. ' + + 'Please close any GPU intensive applications and try again.\n' + + 'If the error persists, your GPU might not be supported.') , + CUDA_RUNTIME_ERROR: + (f'Your PC cannot process this audio file with the chunk size selected. Please lower the chunk size and try again.\n\n{CONTACT_DEV}'), + DEMUCS_MODEL_MISSING_ERROR: + ('The selected Demucs model is missing. ' + + 'Please download the model or make sure it is in the correct directory.'), + ENSEMBLE_MISSING_MODEL_ERROR: + ('The application was unable to locate a model you selected for this ensemble.\n\n' + + 'Please do the following to use all compatible models:\n\n1. Navigate to the \"Updates\" tab in the Help Guide.\n2. Download and install the model expansion pack.\n3. Then try again.\n\n' + + 'If the error persists, please verify all models are present.'), + FFMPEG_MISSING_ERROR: + ('The input file type is not supported or FFmpeg is missing. Please select a file type supported by FFmpeg and try again. ' + + 'If FFmpeg is missing or not installed, you will only be able to process \".wav\" files until it is available on this system. ' + + f'See the \"More Info\" tab in the Help Guide.\n\n{CONTACT_DEV}'), + FILE_MISSING_ERROR: + (f'Missing file error raised. Please address the error and try again.\n\n{CONTACT_DEV}'), + MDX_MEMORY_ERROR: + ('The application was unable to allocate enough GPU memory to use this model.\n\n' + + 'Please do the following:\n\n1. Close any GPU intensive applications.\n2. Lower the set chunk size.\n3. Then try again.\n\n' + + 'If the error persists, your GPU might not be supported.'), + MDX_MODEL_MISSING: + ('The application could not detect this MDX-Net model on your system. ' + + 'Please make sure all the models are present in the correct directory.\n\n' + + 'If the error persists, please reinstall application or contact the developers.'), + MDX_RUNTIME_ERROR: + ('The application was unable to allocate enough GPU memory to use this model.\n\n' + + 'Please do the following:\n\n1. Close any GPU intensive applications.\n2. Lower the set chunk size.\n3. Then try again.\n\n' + + 'If the error persists, your GPU might not be supported.'), + WINDOW_SIZE_ERROR: + ('Invalid window size.\n\n' + + 'The chosen window size is likely not compatible with this model. Please select a different size and try again.'), + SF_WRITE_ERROR: + ('Could not write audio file.\n\n' + + 'This could be due to one of the following:\n\n1. Low storage on target device.\n2. The export directory no longer exists.\n3. A system permissions issue.'), + SYSTEM_MEMORY_ERROR: + ('The application was unable to allocate enough system memory to use this model.\n\n' + + 'Please do the following:\n\n1. Restart this application.\n2. Ensure any CPU intensive applications are closed.\n3. Then try again.\n\n' + + 'Please Note: Intel Pentium and Intel Celeron processors do not work well with this application.\n\n' + + 'If the error persists, the system may not have enough RAM, or your CPU might not be supported.'), + MISSING_MODEL_ERROR: + ('Model Missing: The application was unable to locate the chosen model.\n\n' + + 'If the error persists, please verify any selected models are present.'), + GPU_INCOMPATIBLE_ERROR: + ('This process is not compatible with your GPU.\n\n' + + 'Please uncheck \"GPU Conversion\" and try again'), + ARRAY_SIZE_ERROR: + ('The application was not able to process the given audiofile. Please convert the audiofile to another format and try again.'), +} + +def error_text(process_method, exception): + + traceback_text = ''.join(traceback.format_tb(exception.__traceback__)) + message = f'{type(exception).__name__}: "{exception}"\nTraceback Error: "\n{traceback_text}"\n' + error_message = f'\n\nRaw Error Details:\n\n{message}\nError Time Stamp [{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}]\n' + process = f'Last Error Received:\n\nProcess: {process_method}\n\n' + + for error_type, full_text in ERROR_MAPPER.items(): + if error_type in message: + final_message = full_text + break + else: + final_message = (CONTACT_DEV) + + return f"{process}{final_message}{error_message}" + +def error_dialouge(exception): + + error_name = f'{type(exception).__name__}' + traceback_text = ''.join(traceback.format_tb(exception.__traceback__)) + message = f'{error_name}: "{exception}"\n{traceback_text}"' + + for error_type, full_text in ERROR_MAPPER.items(): + if error_type in message: + final_message = full_text + break + else: + final_message = (f'{error_name}: {exception}\n\n{CONTACT_DEV}') + + return final_message diff --git a/gui_data/fail_chime.wav b/gui_data/fail_chime.wav new file mode 100644 index 0000000000000000000000000000000000000000..85b23b3110c10458612dc75f97556bfc5b4c89f7 Binary files /dev/null and b/gui_data/fail_chime.wav differ diff --git a/gui_data/fonts/centurygothic/GOTHIC.TTF b/gui_data/fonts/centurygothic/GOTHIC.TTF new file mode 100644 index 0000000000000000000000000000000000000000..c60a324123eaaeab58c400c139bcabbc6d0d2a9f Binary files /dev/null and b/gui_data/fonts/centurygothic/GOTHIC.TTF differ diff --git a/gui_data/fonts/centurygothic/GOTHICB.TTF b/gui_data/fonts/centurygothic/GOTHICB.TTF new file mode 100644 index 0000000000000000000000000000000000000000..d3577b960846dd2a9d2cbaceab7b8715b3c5fd54 Binary files /dev/null and b/gui_data/fonts/centurygothic/GOTHICB.TTF differ diff --git a/gui_data/fonts/centurygothic/GOTHICBI.TTF b/gui_data/fonts/centurygothic/GOTHICBI.TTF new file mode 100644 index 0000000000000000000000000000000000000000..d01cefabe3f5aac0dca611b750d07215cfe00dbf Binary files /dev/null and b/gui_data/fonts/centurygothic/GOTHICBI.TTF differ diff --git a/gui_data/fonts/centurygothic/GOTHICI.TTF b/gui_data/fonts/centurygothic/GOTHICI.TTF new file mode 100644 index 0000000000000000000000000000000000000000..777a6d87f5de328998284ce7c4a0df169a6474a2 Binary files /dev/null and b/gui_data/fonts/centurygothic/GOTHICI.TTF differ diff --git a/gui_data/img/File.png b/gui_data/img/File.png new file mode 100644 index 0000000000000000000000000000000000000000..f0efc7d4547a3c85cae3630c2765bf4cf5c90af7 Binary files /dev/null and b/gui_data/img/File.png differ diff --git a/gui_data/img/GUI-Icon.ico b/gui_data/img/GUI-Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c3169b948c581e16a70babeaf782079433d63ae5 Binary files /dev/null and b/gui_data/img/GUI-Icon.ico differ diff --git a/gui_data/img/GUI-Icon.png b/gui_data/img/GUI-Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..db628961474f7f2dfa8218a4210eee2e8b9549eb Binary files /dev/null and b/gui_data/img/GUI-Icon.png differ diff --git a/gui_data/img/UVR-banner.png b/gui_data/img/UVR-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..cc411d56e483b1a41000973d485393adb3fadb87 Binary files /dev/null and b/gui_data/img/UVR-banner.png differ diff --git a/gui_data/img/UVR_5_5_0.png b/gui_data/img/UVR_5_5_0.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5a89dc78cca01c86596e3c73feec0f0de372dc Binary files /dev/null and b/gui_data/img/UVR_5_5_0.png differ diff --git a/gui_data/img/UVR_5_5_1.png b/gui_data/img/UVR_5_5_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd5f17aa48219839dd88a232b4df96ffa170e6d Binary files /dev/null and b/gui_data/img/UVR_5_5_1.png differ diff --git a/gui_data/img/UVR_v5_5_MacOS.png b/gui_data/img/UVR_v5_5_MacOS.png new file mode 100644 index 0000000000000000000000000000000000000000..16e99edd6e18e1d4d252332388754e7d8c5064c2 Binary files /dev/null and b/gui_data/img/UVR_v5_5_MacOS.png differ diff --git a/gui_data/img/credits.png b/gui_data/img/credits.png new file mode 100644 index 0000000000000000000000000000000000000000..f32a49465093d4217e9e6625151da7a34ed09684 Binary files /dev/null and b/gui_data/img/credits.png differ diff --git a/gui_data/img/donate.png b/gui_data/img/donate.png new file mode 100644 index 0000000000000000000000000000000000000000..75341dfbc8afaae6be9121ab3d1e6aecbde841fb Binary files /dev/null and b/gui_data/img/donate.png differ diff --git a/gui_data/img/download.png b/gui_data/img/download.png new file mode 100644 index 0000000000000000000000000000000000000000..3e9e3f642ae1124bd8ffe4baf68cacebd827b507 Binary files /dev/null and b/gui_data/img/download.png differ diff --git a/gui_data/img/help.png b/gui_data/img/help.png new file mode 100644 index 0000000000000000000000000000000000000000..fb576bb21e10a263cccf77c413ae807e7e317bf7 Binary files /dev/null and b/gui_data/img/help.png differ diff --git a/gui_data/img/key.png b/gui_data/img/key.png new file mode 100644 index 0000000000000000000000000000000000000000..35a5a19520d7bf1f78d3e9f65fd61ff292b56490 Binary files /dev/null and b/gui_data/img/key.png differ diff --git a/gui_data/img/pause.png b/gui_data/img/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..819b46570f461c6402aef7ac51896ec5f15a7f28 Binary files /dev/null and b/gui_data/img/pause.png differ diff --git a/gui_data/img/play.png b/gui_data/img/play.png new file mode 100644 index 0000000000000000000000000000000000000000..d01b06a835795ffe7c0980930364108069b30614 Binary files /dev/null and b/gui_data/img/play.png differ diff --git a/gui_data/img/splash.bmp b/gui_data/img/splash.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c1d053c8c0c9c36cc49bd5e45e9411062dbfad90 Binary files /dev/null and b/gui_data/img/splash.bmp differ diff --git a/gui_data/img/stop.png b/gui_data/img/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..e094d1b66cbf6a7777aae2cf2656ba1ca7272641 Binary files /dev/null and b/gui_data/img/stop.png differ diff --git a/gui_data/img/stop_player.png b/gui_data/img/stop_player.png new file mode 100644 index 0000000000000000000000000000000000000000..8eccf6bd82b0e2a4b9674ef9e4939da106a9a22b Binary files /dev/null and b/gui_data/img/stop_player.png differ diff --git a/gui_data/old_data_check.py b/gui_data/old_data_check.py new file mode 100644 index 0000000000000000000000000000000000000000..1694baedc64de4b240bd3afb4d2e35b4e2dd65e3 --- /dev/null +++ b/gui_data/old_data_check.py @@ -0,0 +1,27 @@ +import os +import shutil + +def file_check(original_dir, new_dir): + + if os.path.isdir(original_dir): + for file in os.listdir(original_dir): + shutil.move(os.path.join(original_dir, file), os.path.join(new_dir, file)) + + if len(os.listdir(original_dir)) == 0: + shutil.rmtree(original_dir) + +def remove_unneeded_yamls(demucs_dir): + + for file in os.listdir(demucs_dir): + if file.endswith('.yaml'): + if os.path.isfile(os.path.join(demucs_dir, file)): + os.remove(os.path.join(demucs_dir, file)) + +def remove_temps(remove_dir): + + if os.path.isdir(remove_dir): + try: + shutil.rmtree(remove_dir) + except Exception as e: + print(e) + \ No newline at end of file diff --git a/gui_data/saved_ensembles/saved_ensembles_go_here.txt b/gui_data/saved_ensembles/saved_ensembles_go_here.txt new file mode 100644 index 0000000000000000000000000000000000000000..92b9d07ac6daa72cd49ac47d56d7eba768008a1c --- /dev/null +++ b/gui_data/saved_ensembles/saved_ensembles_go_here.txt @@ -0,0 +1 @@ +saved_ensembles_go_here \ No newline at end of file diff --git a/gui_data/saved_settings/saved_settings_go_here.txt b/gui_data/saved_settings/saved_settings_go_here.txt new file mode 100644 index 0000000000000000000000000000000000000000..b2138571a522140636df40b497456204e20db480 --- /dev/null +++ b/gui_data/saved_settings/saved_settings_go_here.txt @@ -0,0 +1 @@ +saved_settings_go_here \ No newline at end of file diff --git a/gui_data/sv_ttk/__init__.py b/gui_data/sv_ttk/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..978626b64b98b6a6265e6389d74893614f0fc825 --- /dev/null +++ b/gui_data/sv_ttk/__init__.py @@ -0,0 +1,67 @@ +from pathlib import Path +import platform + +if platform.system() == "Darwin": + sun_valley_tcl = "sun-valley_darwin.tcl" +else: + sun_valley_tcl = "sun-valley.tcl" + +inited = False +root = None + + +def init(func): + def wrapper(*args, **kwargs): + global inited + global root + + if not inited: + from tkinter import _default_root + + path = (Path(__file__).parent / sun_valley_tcl).resolve() + + try: + _default_root.tk.call("source", str(path)) + except AttributeError: + raise RuntimeError( + "can't set theme. " + "Tk is not initialized. " + "Please first create a tkinter.Tk instance, then set the theme." + ) from None + else: + inited = True + root = _default_root + + return func(*args, **kwargs) + + return wrapper + + +@init +def set_theme(theme): + if theme not in {"dark", "light"}: + raise RuntimeError(f"not a valid theme name: {theme}") + + root.tk.call("set_theme", theme) + + +@init +def get_theme(): + theme = root.tk.call("ttk::style", "theme", "use") + + try: + return {"sun-valley-dark": "dark", "sun-valley-light": "light"}[theme] + except KeyError: + return theme + + +@init +def toggle_theme(): + if get_theme() == "dark": + use_light_theme() + else: + use_dark_theme() + + +use_dark_theme = lambda: set_theme("dark") +use_light_theme = lambda: set_theme("light") diff --git a/gui_data/sv_ttk/sun-valley.tcl b/gui_data/sv_ttk/sun-valley.tcl new file mode 100644 index 0000000000000000000000000000000000000000..029666977eeb5e8a2b91dd77dfcf71a2c8be17a4 --- /dev/null +++ b/gui_data/sv_ttk/sun-valley.tcl @@ -0,0 +1,49 @@ +# Copyright © 2021 rdbende + +source [file join [file dirname [info script]] theme dark.tcl] + +option add *tearOff 0 + +proc set_theme {mode} { + if {$mode == "dark"} { + ttk::style theme use "sun-valley-dark" + + array set colors { + -fg "#F6F6F7" + -bg "#0e0e0f" + -disabledfg "#F6F6F7" + -selectfg "#F6F6F7" + -selectbg "#003b50" + } + + ttk::style configure . \ + -background $colors(-bg) \ + -foreground $colors(-fg) \ + -troughcolor $colors(-bg) \ + -focuscolor $colors(-selectbg) \ + -selectbackground $colors(-selectbg) \ + -selectforeground $colors(-selectfg) \ + -insertwidth 0 \ + -insertcolor $colors(-fg) \ + -fieldbackground $colors(-selectbg) \ + -font {"Century Gothic" 10} \ + -borderwidth 0 \ + -relief flat + + tk_setPalette \ + background [ttk::style lookup . -background] \ + foreground [ttk::style lookup . -foreground] \ + highlightColor [ttk::style lookup . -focuscolor] \ + selectBackground [ttk::style lookup . -selectbackground] \ + selectForeground [ttk::style lookup . -selectforeground] \ + activeBackground [ttk::style lookup . -selectbackground] \ + activeForeground [ttk::style lookup . -selectforeground] + + ttk::style map . -foreground [list disabled $colors(-disabledfg)] + + option add *font [ttk::style lookup . -font] + option add *Menu.selectcolor $colors(-fg) + option add *Menu.background #0e0e0f + + } +} diff --git a/gui_data/sv_ttk/sun-valley_darwin.tcl b/gui_data/sv_ttk/sun-valley_darwin.tcl new file mode 100644 index 0000000000000000000000000000000000000000..f76c5350ec64d605f4acda14075e9fc9497fa311 --- /dev/null +++ b/gui_data/sv_ttk/sun-valley_darwin.tcl @@ -0,0 +1,49 @@ +# Copyright © 2021 rdbende + +source [file join [file dirname [info script]] theme dark.tcl] + +option add *tearOff 0 + +proc set_theme {mode} { + if {$mode == "dark"} { + ttk::style theme use "sun-valley-dark" + + array set colors { + -fg "#F6F6F7" + -bg "#0e0e0f" + -disabledfg "#F6F6F7" + -selectfg "#F6F6F7" + -selectbg "#003b50" + } + + ttk::style configure . \ + -background $colors(-bg) \ + -foreground $colors(-fg) \ + -troughcolor $colors(-bg) \ + -focuscolor $colors(-selectbg) \ + -selectbackground $colors(-selectbg) \ + -selectforeground $colors(-selectfg) \ + -insertwidth 0 \ + -insertcolor $colors(-fg) \ + -fieldbackground $colors(-selectbg) \ + -font {"Century Gothic" 13} \ + -borderwidth 0 \ + -relief flat + + tk_setPalette \ + background [ttk::style lookup . -background] \ + foreground [ttk::style lookup . -foreground] \ + highlightColor [ttk::style lookup . -focuscolor] \ + selectBackground [ttk::style lookup . -selectbackground] \ + selectForeground [ttk::style lookup . -selectforeground] \ + activeBackground [ttk::style lookup . -selectbackground] \ + activeForeground [ttk::style lookup . -selectforeground] + + ttk::style map . -foreground [list disabled $colors(-disabledfg)] + + option add *font [ttk::style lookup . -font] + option add *Menu.selectcolor $colors(-fg) + option add *Menu.background #0e0e0f + + } +} diff --git a/gui_data/sv_ttk/theme/dark.tcl b/gui_data/sv_ttk/theme/dark.tcl new file mode 100644 index 0000000000000000000000000000000000000000..82cf971c8d773a016b1f390ccd0f2a2cc0bb8888 --- /dev/null +++ b/gui_data/sv_ttk/theme/dark.tcl @@ -0,0 +1,540 @@ +# Copyright © 2021 rdbende + +# A stunning dark theme for ttk based on Microsoft's Sun Valley visual style + +package require Tk 8.6 + +namespace eval ttk::theme::sun-valley-dark { + variable version 1.0 + package provide ttk::theme::sun-valley-dark $version + + ttk::style theme create sun-valley-dark -parent clam -settings { + proc load_images {imgdir} { + variable images + foreach file [glob -directory $imgdir *.png] { + set images([file tail [file rootname $file]]) \ + [image create photo -file $file -format png] + } + } + + load_images [file join [file dirname [info script]] dark] + + array set colors { + -fg "#F6F6F7" + -bg "#0e0e0f" + -disabledfg "#F6F6F7" + -selectfg "#ffffff" + -selectbg "#2f60d8" + } + + ttk::style layout TButton { + Button.button -children { + Button.padding -children { + Button.label -side left -expand 1 + } + } + } + + ttk::style layout Toolbutton { + Toolbutton.button -children { + Toolbutton.padding -children { + Toolbutton.label -side left -expand 1 + } + } + } + + ttk::style layout TMenubutton { + Menubutton.button -children { + Menubutton.padding -children { + Menubutton.label -side left -expand 1 + Menubutton.indicator -side right -sticky nsew + } + } + } + + ttk::style layout TOptionMenu { + OptionMenu.button -children { + OptionMenu.padding -children { + OptionMenu.label -side left -expand 0 + OptionMenu.indicator -side right -sticky nsew + } + } + } + + ttk::style layout Accent.TButton { + AccentButton.button -children { + AccentButton.padding -children { + AccentButton.label -side left -expand 1 + } + } + } + + ttk::style layout Titlebar.TButton { + TitlebarButton.button -children { + TitlebarButton.padding -children { + TitlebarButton.label -side left -expand 1 + } + } + } + + ttk::style layout Close.Titlebar.TButton { + CloseButton.button -children { + CloseButton.padding -children { + CloseButton.label -side left -expand 1 + } + } + } + + ttk::style layout TCheckbutton { + Checkbutton.button -children { + Checkbutton.padding -children { + Checkbutton.indicator -side left + Checkbutton.label -side right -expand 1 + } + } + } + + ttk::style layout Switch.TCheckbutton { + Switch.button -children { + Switch.padding -children { + Switch.indicator -side left + Switch.label -side right -expand 1 + } + } + } + + ttk::style layout Toggle.TButton { + ToggleButton.button -children { + ToggleButton.padding -children { + ToggleButton.label -side left -expand 1 + } + } + } + + ttk::style layout TRadiobutton { + Radiobutton.button -children { + Radiobutton.padding -children { + Radiobutton.indicator -side left + Radiobutton.label -side right -expand 1 + } + } + } + + ttk::style layout Vertical.TScrollbar { + Vertical.Scrollbar.trough -sticky ns -children { + Vertical.Scrollbar.uparrow -side top + Vertical.Scrollbar.downarrow -side bottom + Vertical.Scrollbar.thumb -expand 1 + } + } + + ttk::style layout Horizontal.TScrollbar { + Horizontal.Scrollbar.trough -sticky ew -children { + Horizontal.Scrollbar.leftarrow -side left + Horizontal.Scrollbar.rightarrow -side right + Horizontal.Scrollbar.thumb -expand 1 + } + } + + ttk::style layout TSeparator { + TSeparator.separator -sticky nsew + } + + ttk::style layout TCombobox { + Combobox.field -sticky nsew -children { + Combobox.padding -expand 1 -sticky nsew -children { + Combobox.textarea -sticky nsew + } + } + null -side right -sticky ns -children { + Combobox.arrow -sticky nsew + } + } + + ttk::style layout TSpinbox { + Spinbox.field -sticky nsew -children { + Spinbox.padding -expand 1 -sticky nsew -children { + Spinbox.textarea -sticky nsew + } + + } + null -side right -sticky nsew -children { + Spinbox.uparrow -side left -sticky nsew + Spinbox.downarrow -side right -sticky nsew + } + } + + ttk::style layout Card.TFrame { + Card.field { + Card.padding -expand 1 + } + } + + ttk::style layout TLabelframe { + Labelframe.border { + Labelframe.padding -expand 1 -children { + Labelframe.label -side left + } + } + } + + ttk::style layout TNotebook { + Notebook.border -children { + TNotebook.Tab -expand 1 + Notebook.client -sticky nsew + } + } + + ttk::style layout Treeview.Item { + Treeitem.padding -sticky nsew -children { + Treeitem.image -side left -sticky {} + Treeitem.indicator -side left -sticky {} + Treeitem.text -side left -sticky {} + } + } + + # Button + ttk::style configure TButton -padding {8 4} -anchor center -foreground $colors(-fg) + + ttk::style map TButton -foreground \ + [list disabled #7a7a7a \ + pressed #d0d0d0] + + ttk::style element create Button.button image \ + [list $images(button-rest) \ + {selected disabled} $images(button-disabled) \ + disabled $images(button-disabled) \ + selected $images(button-rest) \ + pressed $images(button-pressed) \ + active $images(button-hover) \ + ] -border 4 -sticky nsew + + # Toolbutton + ttk::style configure Toolbutton -padding {8 4} -anchor center + + ttk::style element create Toolbutton.button image \ + [list $images(empty) \ + {selected disabled} $images(button-disabled) \ + selected $images(button-rest) \ + pressed $images(button-pressed) \ + active $images(button-hover) \ + ] -border 4 -sticky nsew + + # Menubutton + ttk::style configure TMenubutton -padding {8 4 0 4} + + ttk::style element create Menubutton.button \ + image [list $images(button-rest) \ + disabled $images(button-disabled) \ + pressed $images(button-pressed) \ + active $images(button-hover) \ + ] -border 4 -sticky nsew + + ttk::style element create Menubutton.indicator image $images(arrow-down) -width 28 -sticky {} + + # OptionMenu + ttk::style configure TOptionMenu -padding {8 4 0 4} + ttk::style configure OptionMenudropdown -borderwidth 0 -relief ridge + + ttk::style element create OptionMenu.button \ + image [list $images(button-rest) \ + disabled $images(button-disabled) \ + pressed $images(button-pressed) \ + active $images(button-hover) \ + ] -border 0 -sticky nsew + + ttk::style element create OptionMenu.indicator image $images(arrow-down) -width 28 -sticky {} + + # Accent.TButton + ttk::style configure Accent.TButton -padding {8 4} -anchor center -foreground #ffffff + + ttk::style map Accent.TButton -foreground \ + [list pressed #25536a \ + disabled #a5a5a5] + + ttk::style element create AccentButton.button image \ + [list $images(button-accent-rest) \ + {selected disabled} $images(button-accent-disabled) \ + disabled $images(button-accent-disabled) \ + selected $images(button-accent-rest) \ + pressed $images(button-accent-pressed) \ + active $images(button-accent-hover) \ + ] -border 4 -sticky nsew + + # Titlebar.TButton + ttk::style configure Titlebar.TButton -padding {8 4} -anchor center -foreground #ffffff + + ttk::style map Titlebar.TButton -foreground \ + [list disabled #6f6f6f \ + pressed #d1d1d1 \ + active #ffffff] + + ttk::style element create TitlebarButton.button image \ + [list $images(empty) \ + disabled $images(empty) \ + pressed $images(button-titlebar-pressed) \ + active $images(button-titlebar-hover) \ + ] -border 4 -sticky nsew + + # Close.Titlebar.TButton + ttk::style configure Close.Titlebar.TButton -padding {8 4} -anchor center -foreground #ffffff + + ttk::style map Close.Titlebar.TButton -foreground \ + [list disabled #6f6f6f \ + pressed #e8bfbb \ + active #ffffff] + + ttk::style element create CloseButton.button image \ + [list $images(empty) \ + disabled $images(empty) \ + pressed $images(button-close-pressed) \ + active $images(button-close-hover) \ + ] -border 4 -sticky nsew + + # Checkbutton + ttk::style configure TCheckbutton -padding 2 + + ttk::style element create Checkbutton.indicator image \ + [list $images(check-unsel-rest) \ + {alternate disabled} $images(check-tri-disabled) \ + {selected disabled} $images(check-disabled) \ + disabled $images(check-unsel-disabled) \ + {pressed alternate} $images(check-tri-hover) \ + {active alternate} $images(check-tri-hover) \ + alternate $images(check-tri-rest) \ + {pressed selected} $images(check-hover) \ + {active selected} $images(check-hover) \ + selected $images(check-rest) \ + {pressed !selected} $images(check-unsel-pressed) \ + active $images(check-unsel-hover) \ + ] -width 26 -sticky w + + # Switch.TCheckbutton + ttk::style element create Switch.indicator image \ + [list $images(switch-off-rest) \ + {selected disabled} $images(switch-on-disabled) \ + disabled $images(switch-off-disabled) \ + {pressed selected} $images(switch-on-pressed) \ + {active selected} $images(switch-on-hover) \ + selected $images(switch-on-rest) \ + {pressed !selected} $images(switch-off-pressed) \ + active $images(switch-off-hover) \ + ] -width 46 -sticky w + + # Toggle.TButton + ttk::style configure Toggle.TButton -padding {8 4 8 4} -anchor center -foreground $colors(-fg) + + ttk::style map Toggle.TButton -foreground \ + [list {selected disabled} #a5a5a5 \ + {selected pressed} #d0d0d0 \ + selected #ffffff \ + pressed #25536a \ + disabled #7a7a7a + ] + + + ttk::style element create ToggleButton.button image \ + [list $images(button-rest) \ + {selected disabled} $images(button-accent-disabled) \ + disabled $images(button-disabled) \ + {pressed selected} $images(button-rest) \ + {active selected} $images(button-accent-hover) \ + selected $images(button-accent-rest) \ + {pressed !selected} $images(button-accent-rest) \ + active $images(button-hover) \ + ] -border 4 -sticky nsew + + # Radiobutton + ttk::style configure TRadiobutton -padding 0 + + ttk::style element create Radiobutton.indicator image \ + [list $images(radio-unsel-rest) \ + {selected disabled} $images(radio-disabled) \ + disabled $images(radio-unsel-disabled) \ + {pressed selected} $images(radio-pressed) \ + {active selected} $images(radio-hover) \ + selected $images(radio-rest) \ + {pressed !selected} $images(radio-unsel-pressed) \ + active $images(radio-unsel-hover) \ + ] -width 20 -sticky w + + ttk::style configure Menu.TRadiobutton -padding 0 + + ttk::style element create Menu.Radiobutton.indicator image \ + [list $images(radio-unsel-rest) \ + {selected disabled} $images(radio-disabled) \ + disabled $images(radio-unsel-disabled) \ + {pressed selected} $images(radio-pressed) \ + {active selected} $images(radio-hover) \ + selected $images(radio-rest) \ + {pressed !selected} $images(radio-unsel-pressed) \ + active $images(radio-unsel-hover) \ + ] -width 20 -sticky w + + # Scrollbar + + #ttk::style layout Vertical.TScrollbar + + ttk::style element create Horizontal.Scrollbar.trough image $images(scroll-hor-trough) -sticky ew -border 0 + ttk::style element create Horizontal.Scrollbar.thumb image $images(scroll-hor-thumb) -sticky ew -border 3 + + ttk::style element create Horizontal.Scrollbar.rightarrow image $images(scroll-right) -sticky {} -width 13 + ttk::style element create Horizontal.Scrollbar.leftarrow image $images(scroll-left) -sticky {} -width 13 + + ttk::style element create Vertical.Scrollbar.trough image $images(scroll-vert-trough) -sticky ns -border 0 + ttk::style element create Vertical.Scrollbar.thumb image $images(scroll-vert-thumb) -sticky ns -border 3 + + ttk::style element create Vertical.Scrollbar.uparrow image $images(scroll-up) -sticky {} -height 13 + ttk::style element create Vertical.Scrollbar.downarrow image $images(scroll-down) -sticky {} -height 13 + + # Scale + ttk::style element create Horizontal.Scale.trough image $images(scale-trough-hor) \ + -border 5 -padding 0 + + ttk::style element create Vertical.Scale.trough image $images(scale-trough-vert) \ + -border 5 -padding 0 + + ttk::style element create Scale.slider \ + image [list $images(scale-thumb-rest) \ + disabled $images(scale-thumb-disabled) \ + pressed $images(scale-thumb-pressed) \ + active $images(scale-thumb-hover) \ + ] -sticky {} + + # Progressbar + ttk::style element create Horizontal.Progressbar.trough image $images(progress-trough-hor) \ + -border 1 -sticky ew + + ttk::style element create Horizontal.Progressbar.pbar image $images(progress-pbar-hor) \ + -border 2 -sticky ew + + ttk::style element create Vertical.Progressbar.trough image $images(progress-trough-vert) \ + -border 1 -sticky ns + + ttk::style element create Vertical.Progressbar.pbar image $images(progress-pbar-vert) \ + -border 2 -sticky ns + + # Entry + ttk::style configure TEntry -foreground $colors(-fg) + + ttk::style map TEntry -foreground \ + [list disabled #757575 \ + pressed #cfcfcf + ] + + ttk::style element create Entry.field \ + image [list $images(entry-rest) \ + {focus hover !invalid} $images(entry-focus) \ + invalid $images(entry-invalid) \ + disabled $images(entry-disabled) \ + {focus !invalid} $images(entry-focus) \ + hover $images(entry-hover) \ + ] -border 5 -padding 8 -sticky nsew + + # Combobox + ttk::style configure TCombobox -foreground $colors(-fg) + + ttk::style map TCombobox -foreground \ + [list disabled #757575 \ + pressed #cfcfcf + ] + + ttk::style configure TCombobox -foreground $colors(-fg) + ttk::style configure ComboboxPopdownFrame -borderwidth 3 -relief solid + + ttk::style map TCombobox -selectbackground [list \ + {readonly hover} $colors(-selectbg) \ + {readonly focus} $colors(-selectbg) \ + ] -selectforeground [list \ + {readonly hover} $colors(-selectfg) \ + {readonly focus} $colors(-selectfg) \ + ] + + ttk::style element create Combobox.field \ + image [list $images(button-rest) \ + {readonly disabled} $images(button-disabled) \ + {readonly pressed} $images(button-pressed) \ + {readonly hover} $images(button-hover) \ + readonly $images(button-rest) \ + invalid $images(entry-invalid) \ + disabled $images(entry-disabled) \ + focus $images(entry-focus) \ + hover $images(button-hover) \ + ] -border 5 -padding 8 -sticky nsew + + ttk::style element create Combobox.arrow image $images(arrow-down) -width 35 -sticky {} + + # Spinbox + ttk::style configure TSpinbox -foreground $colors(-fg) + + ttk::style map TSpinbox -foreground \ + [list disabled #757575 \ + pressed #cfcfcf + ] + + ttk::style element create Spinbox.field \ + image [list $images(entry-rest) \ + invalid $images(entry-invalid) \ + disabled $images(entry-disabled) \ + focus $images(entry-focus) \ + hover $images(entry-hover) \ + ] -border 5 -padding {8 8 54 8} -sticky nsew + + ttk::style element create Spinbox.uparrow image $images(arrow-up) -width 35 -sticky {} + ttk::style element create Spinbox.downarrow image $images(arrow-down) -width 35 -sticky {} + + # Sizegrip + ttk::style element create Sizegrip.sizegrip image $images(sizegrip) \ + -sticky nsew + + # Separator + ttk::style element create TSeparator.separator image $images(separator) + + # Card + ttk::style element create Card.field image $images(card) \ + -border 10 -padding 4 -sticky nsew + + # Labelframe + ttk::style element create Labelframe.border image $images(card) \ + -border 5 -padding 4 -sticky nsew + + # Notebook + ttk::style configure TNotebook -padding 1 + + ttk::style element create Notebook.border \ + image $images(notebook-border) -border 5 -padding 5 + + ttk::style element create Notebook.client image $images(notebook) + + ttk::style element create Notebook.tab \ + image [list $images(tab-rest) \ + selected $images(tab-selected) \ + active $images(tab-hover) \ + ] -border 13 -padding {16 14 16 6} -height 32 + + # Treeview + ttk::style element create Treeview.field image $images(card) \ + -border 5 + + ttk::style element create Treeheading.cell \ + image [list $images(treeheading-rest) \ + pressed $images(treeheading-pressed) \ + active $images(treeheading-hover) + ] -border 5 -padding 15 -sticky nsew + + ttk::style element create Treeitem.indicator \ + image [list $images(arrow-right) \ + user2 $images(empty) \ + user1 $images(arrow-down) \ + ] -width 26 -sticky {} + + ttk::style configure Treeview -background $colors(-bg) -rowheight [expr {[font metrics font -linespace] + 2}] + ttk::style map Treeview \ + -background [list selected #292929] \ + -foreground [list selected $colors(-selectfg)] + + # Panedwindow + # Insane hack to remove clam's ugly sash + ttk::style configure Sash -gripcount 0 + } +} \ No newline at end of file diff --git a/gui_data/sv_ttk/theme/dark/arrow-down.png b/gui_data/sv_ttk/theme/dark/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..2b0a9d8d4da574230214360781df04f68754ddd5 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/arrow-down.png differ diff --git a/gui_data/sv_ttk/theme/dark/arrow-right.png b/gui_data/sv_ttk/theme/dark/arrow-right.png new file mode 100644 index 0000000000000000000000000000000000000000..2638d885eb9be2833b009ef5b88081a4b22b34b2 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/arrow-right.png differ diff --git a/gui_data/sv_ttk/theme/dark/arrow-up.png b/gui_data/sv_ttk/theme/dark/arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..f935a0d32a699308758f10b1ccee21c92e7c6b64 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/arrow-up.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-accent-disabled.png b/gui_data/sv_ttk/theme/dark/button-accent-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..bf7bd9ba70f9371a9c3d98b8f97039e611018479 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-accent-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-accent-hover.png b/gui_data/sv_ttk/theme/dark/button-accent-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..8aea9dd682773a2a5ed32f6a9c14a4db8f2c00ac Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-accent-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-accent-pressed.png b/gui_data/sv_ttk/theme/dark/button-accent-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..edc1114e5e03094ebe8796dd528ca5fb932ec9eb Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-accent-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-accent-rest.png b/gui_data/sv_ttk/theme/dark/button-accent-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..75e64f84d1f8e6cf20777de748c2cf54e53e9faf Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-accent-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-close-hover.png b/gui_data/sv_ttk/theme/dark/button-close-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..6fc0c00cc7d742753dc71c0add0fb32fc7756b8c Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-close-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-close-pressed.png b/gui_data/sv_ttk/theme/dark/button-close-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..6023dc1435a0288cf824533d496312b237fdf8b8 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-close-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-disabled.png b/gui_data/sv_ttk/theme/dark/button-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..71bb0a8f261f00a67737cc58c47511c236d80c41 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-hover.png b/gui_data/sv_ttk/theme/dark/button-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..20413753ca1b8d669bd5594a9c82da521a95b65d Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-pressed.png b/gui_data/sv_ttk/theme/dark/button-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..42701498d18f5361bf3cff92033cabc845565217 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-rest.png b/gui_data/sv_ttk/theme/dark/button-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..128f5f68e4a2d4902842c4e73999094247c8f28f Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-titlebar-hover.png b/gui_data/sv_ttk/theme/dark/button-titlebar-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..fcb37512f76d28becbc7ece0f26be88ee16892d2 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-titlebar-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/button-titlebar-pressed.png b/gui_data/sv_ttk/theme/dark/button-titlebar-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed0623e8d5bed5e8a24d960b49a3a9e7c6f5ddd Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/button-titlebar-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/card.png b/gui_data/sv_ttk/theme/dark/card.png new file mode 100644 index 0000000000000000000000000000000000000000..eaac11c57163d48359431f46d921f14658d79595 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/card.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-disabled.png b/gui_data/sv_ttk/theme/dark/check-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..f766ebafa3c9fa5b7dcf944e0a8c14961cb9c35a Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-hover.png b/gui_data/sv_ttk/theme/dark/check-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..59358d4b32bee4f9bc58e6104e80d8f902365f28 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-pressed.png b/gui_data/sv_ttk/theme/dark/check-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..02ee6affa06c7e5cfdfc0bae44810dbd76a9ab3b Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-rest.png b/gui_data/sv_ttk/theme/dark/check-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..aa8dc67a880e899d6526dfa5198967e78b8b122e Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-tri-disabled.png b/gui_data/sv_ttk/theme/dark/check-tri-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..a9d31c760240a0deceaf99ab0f3a622de75aab08 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-tri-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-tri-hover.png b/gui_data/sv_ttk/theme/dark/check-tri-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..ed218a0e3c8c18531195f7e33d384183cb8d1738 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-tri-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-tri-pressed.png b/gui_data/sv_ttk/theme/dark/check-tri-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..68d7a993b3eec568eb268c4133d7cba9cf9b9508 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-tri-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-tri-rest.png b/gui_data/sv_ttk/theme/dark/check-tri-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..26edcdb13c66fa429b933f7af6a8ae04a2cc17a2 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-tri-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-unsel-disabled.png b/gui_data/sv_ttk/theme/dark/check-unsel-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..9f4be2293be707fe6d3d64b782de6d6795e4f848 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-unsel-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-unsel-hover.png b/gui_data/sv_ttk/theme/dark/check-unsel-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..a96a0dbd0a2d9d027a809809d61555d597c9193e Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-unsel-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-unsel-pressed.png b/gui_data/sv_ttk/theme/dark/check-unsel-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..26767b8a3e7f367e06f4cf5ebef1a1297d62280f Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-unsel-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/check-unsel-rest.png b/gui_data/sv_ttk/theme/dark/check-unsel-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..128f5f68e4a2d4902842c4e73999094247c8f28f Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/check-unsel-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/empty.png b/gui_data/sv_ttk/theme/dark/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..22183634d5e36298e12ed067750da6c7d2fcdea9 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/empty.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-disabled.png b/gui_data/sv_ttk/theme/dark/entry-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..1d9bce84ddb0c228a3ed5e90364601f5b1eefed2 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-focus.png b/gui_data/sv_ttk/theme/dark/entry-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..58999e476e9af4e7b401bd558c9c85be4b3deeb7 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-focus.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-hover.png b/gui_data/sv_ttk/theme/dark/entry-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..6b93830ab5908d7af96c755acd111761524e0f4e Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-invalid.png b/gui_data/sv_ttk/theme/dark/entry-invalid.png new file mode 100644 index 0000000000000000000000000000000000000000..7304b247cd136a2042d9ef347406655172be6537 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-invalid.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-rest-combo.png b/gui_data/sv_ttk/theme/dark/entry-rest-combo.png new file mode 100644 index 0000000000000000000000000000000000000000..3f32bba56213a1da4122229c5269abf4ceaa82c6 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-rest-combo.png differ diff --git a/gui_data/sv_ttk/theme/dark/entry-rest.png b/gui_data/sv_ttk/theme/dark/entry-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..e8767526ae057387f873d60cc1ec1ae578b77cec Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/entry-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/notebook-border.png b/gui_data/sv_ttk/theme/dark/notebook-border.png new file mode 100644 index 0000000000000000000000000000000000000000..0827a074e2330c873964133f877788a1fb4cbeb1 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/notebook-border.png differ diff --git a/gui_data/sv_ttk/theme/dark/notebook.png b/gui_data/sv_ttk/theme/dark/notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..15c05f87c1761bf7070eda68c5c2225852343e1a Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/notebook.png differ diff --git a/gui_data/sv_ttk/theme/dark/progress-pbar-hor.png b/gui_data/sv_ttk/theme/dark/progress-pbar-hor.png new file mode 100644 index 0000000000000000000000000000000000000000..f8035f8394d2299bb2ca03f3ff8116d081e4c70c Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/progress-pbar-hor.png differ diff --git a/gui_data/sv_ttk/theme/dark/progress-pbar-vert.png b/gui_data/sv_ttk/theme/dark/progress-pbar-vert.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0cb29758f0c6b066031b946818eeff9731dba4 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/progress-pbar-vert.png differ diff --git a/gui_data/sv_ttk/theme/dark/progress-trough-hor.png b/gui_data/sv_ttk/theme/dark/progress-trough-hor.png new file mode 100644 index 0000000000000000000000000000000000000000..9fe480766ed57accc392f94ead242a1e3761d5d2 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/progress-trough-hor.png differ diff --git a/gui_data/sv_ttk/theme/dark/progress-trough-vert.png b/gui_data/sv_ttk/theme/dark/progress-trough-vert.png new file mode 100644 index 0000000000000000000000000000000000000000..22a8c1c640586e6d8af59d584ff97089b570fec8 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/progress-trough-vert.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-disabled.png b/gui_data/sv_ttk/theme/dark/radio-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..b724f3a2229656060532fab32c3c6fc908bdaa5d Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-hover.png b/gui_data/sv_ttk/theme/dark/radio-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..982334519f74e3784c04e96014b954959ad0a1b8 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-pressed.png b/gui_data/sv_ttk/theme/dark/radio-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..ed89533169d16c5068da1ce9f77ffe6f8438850a Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-rest.png b/gui_data/sv_ttk/theme/dark/radio-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..ef891d151a4807c35408bfbf52c00528b62378d5 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-unsel-disabled.png b/gui_data/sv_ttk/theme/dark/radio-unsel-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4142bb363e4aac1f14a347ca2d99a298d822c8 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-unsel-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-unsel-hover.png b/gui_data/sv_ttk/theme/dark/radio-unsel-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..7feda0b45b355e52771e482c53726ab0e5e2c407 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-unsel-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-unsel-pressed.png b/gui_data/sv_ttk/theme/dark/radio-unsel-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..7a76749185e8ee823a95bc3f0f62ff0e7f1a9abe Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-unsel-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/radio-unsel-rest.png b/gui_data/sv_ttk/theme/dark/radio-unsel-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..f311983f8ec0da215b1c99b3a85856b0acf6f9d7 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/radio-unsel-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-thumb-disabled.png b/gui_data/sv_ttk/theme/dark/scale-thumb-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..329e2630ccf0f3c63c91ac9b0fc72067c90a72ac Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-thumb-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-thumb-hover.png b/gui_data/sv_ttk/theme/dark/scale-thumb-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..84e3d18a5b3ebb5f8ec1ecdfdba948b1ed1ad35c Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-thumb-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-thumb-pressed.png b/gui_data/sv_ttk/theme/dark/scale-thumb-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9925e79f6680ecd5aec1878f8fb5c7505c68be Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-thumb-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-thumb-rest.png b/gui_data/sv_ttk/theme/dark/scale-thumb-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..740437b5bffab5e23b5b9f5a115a94c72deefc62 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-thumb-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-trough-hor.png b/gui_data/sv_ttk/theme/dark/scale-trough-hor.png new file mode 100644 index 0000000000000000000000000000000000000000..264046235b72a383c4434f516ac310ab74a49f02 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-trough-hor.png differ diff --git a/gui_data/sv_ttk/theme/dark/scale-trough-vert.png b/gui_data/sv_ttk/theme/dark/scale-trough-vert.png new file mode 100644 index 0000000000000000000000000000000000000000..205fed89725e9c6399776707dff139f02916abc3 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scale-trough-vert.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-down.png b/gui_data/sv_ttk/theme/dark/scroll-down.png new file mode 100644 index 0000000000000000000000000000000000000000..4c0e24fa06c2478235e21ac90290d52cbe893c0a Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-down.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-hor-thumb.png b/gui_data/sv_ttk/theme/dark/scroll-hor-thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..795a88a783f0f550e52469479672e0a238e86d5f Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-hor-thumb.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-hor-trough.png b/gui_data/sv_ttk/theme/dark/scroll-hor-trough.png new file mode 100644 index 0000000000000000000000000000000000000000..89d04035b472f791ab57dc0443a8b7f70b39d3e1 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-hor-trough.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-left.png b/gui_data/sv_ttk/theme/dark/scroll-left.png new file mode 100644 index 0000000000000000000000000000000000000000..f43538b8ac001aac048d41cdd92f2a349649fda9 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-left.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-right.png b/gui_data/sv_ttk/theme/dark/scroll-right.png new file mode 100644 index 0000000000000000000000000000000000000000..a56511f0fc18526f223fc850507831ca7bec0dbb Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-right.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-up.png b/gui_data/sv_ttk/theme/dark/scroll-up.png new file mode 100644 index 0000000000000000000000000000000000000000..7ddba7fff7796e7f279467b5fc1acbfbe765ad53 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-up.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-vert-thumb.png b/gui_data/sv_ttk/theme/dark/scroll-vert-thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..0c3f067a3b3092053057dddee1566fd9c65a8fbf Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-vert-thumb.png differ diff --git a/gui_data/sv_ttk/theme/dark/scroll-vert-trough.png b/gui_data/sv_ttk/theme/dark/scroll-vert-trough.png new file mode 100644 index 0000000000000000000000000000000000000000..52fd58f3049e992f600fa9c37d5cc3768c83493d Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/scroll-vert-trough.png differ diff --git a/gui_data/sv_ttk/theme/dark/separator.png b/gui_data/sv_ttk/theme/dark/separator.png new file mode 100644 index 0000000000000000000000000000000000000000..6e01f551a104e787194301b25e8d12128bb520f6 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/separator.png differ diff --git a/gui_data/sv_ttk/theme/dark/sizegrip.png b/gui_data/sv_ttk/theme/dark/sizegrip.png new file mode 100644 index 0000000000000000000000000000000000000000..7080c04c67807e08452264809cbacf35b89a0503 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/sizegrip.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-off-disabled.png b/gui_data/sv_ttk/theme/dark/switch-off-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..4032c6128b8db875f5c8b3b67ff1a200458ff095 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-off-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-off-hover.png b/gui_data/sv_ttk/theme/dark/switch-off-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..5a136bd3f4c6fd280134f300e5cf50136e217b05 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-off-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-off-pressed.png b/gui_data/sv_ttk/theme/dark/switch-off-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..040e2ea30c96c8fcf103abdb749a706ec9b01975 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-off-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-off-rest.png b/gui_data/sv_ttk/theme/dark/switch-off-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..6c31bb235da79718ef3684ee86a922d44fa470a6 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-off-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-on-disabled.png b/gui_data/sv_ttk/theme/dark/switch-on-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d67c567752d96e322b3f3dcea9cd95bbf8efec Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-on-disabled.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-on-hover.png b/gui_data/sv_ttk/theme/dark/switch-on-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..fd4de9497e12ce541db5e02ffdc02a640dca8f0e Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-on-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-on-pressed.png b/gui_data/sv_ttk/theme/dark/switch-on-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..00e87c68a1b37cde51142d964e4ac1374a69de4f Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-on-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/switch-on-rest.png b/gui_data/sv_ttk/theme/dark/switch-on-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..52a19ea658446caede4fb410192b05bdc78353ef Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/switch-on-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/tab-hover.png b/gui_data/sv_ttk/theme/dark/tab-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..43a113b35c4019897390acd452cda5aab135512a Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/tab-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/tab-rest.png b/gui_data/sv_ttk/theme/dark/tab-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a6f3f61bb7a3aa8bcca71abd5cdefa87f9f801 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/tab-rest.png differ diff --git a/gui_data/sv_ttk/theme/dark/tab-selected.png b/gui_data/sv_ttk/theme/dark/tab-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7b211bbffe6a523e7dd947c1d06af4ce33aa3e Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/tab-selected.png differ diff --git a/gui_data/sv_ttk/theme/dark/treeheading-hover.png b/gui_data/sv_ttk/theme/dark/treeheading-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..beaaf1353fe62c3607118cbabce26b78ec5ceea0 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/treeheading-hover.png differ diff --git a/gui_data/sv_ttk/theme/dark/treeheading-pressed.png b/gui_data/sv_ttk/theme/dark/treeheading-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd311dc6cf1afeee2f326ea640dfa216e6d8738 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/treeheading-pressed.png differ diff --git a/gui_data/sv_ttk/theme/dark/treeheading-rest.png b/gui_data/sv_ttk/theme/dark/treeheading-rest.png new file mode 100644 index 0000000000000000000000000000000000000000..374ed4992d9893965a9489a665e09b9c04ab91c7 Binary files /dev/null and b/gui_data/sv_ttk/theme/dark/treeheading-rest.png differ diff --git a/gui_data/tkinterdnd2/TkinterDnD.py b/gui_data/tkinterdnd2/TkinterDnD.py new file mode 100644 index 0000000000000000000000000000000000000000..8bae5c22fc941e61dbafef89dd5b102367408b36 --- /dev/null +++ b/gui_data/tkinterdnd2/TkinterDnD.py @@ -0,0 +1,294 @@ +'''Python wrapper for the tkdnd tk extension. + +The tkdnd extension provides an interface to native, platform specific +drag and drop mechanisms. Under Unix the drag & drop protocol in use is +the XDND protocol version 5 (also used by the Qt toolkit, and the KDE and +GNOME desktops). Under Windows, the OLE2 drag & drop interfaces are used. +Under Macintosh, the Cocoa drag and drop interfaces are used. + +Once the TkinterDnD2 package is installed, it is safe to do: + +from TkinterDnD2 import * + +This will add the classes TkinterDnD.Tk and TkinterDnD.TixTk to the global +namespace, plus the following constants: +PRIVATE, NONE, ASK, COPY, MOVE, LINK, REFUSE_DROP, +DND_TEXT, DND_FILES, DND_ALL, CF_UNICODETEXT, CF_TEXT, CF_HDROP, +FileGroupDescriptor, FileGroupDescriptorW + +Drag and drop for the application can then be enabled by using one of the +classes TkinterDnD.Tk() or (in case the tix extension shall be used) +TkinterDnD.TixTk() as application main window instead of a regular +tkinter.Tk() window. This will add the drag-and-drop specific methods to the +Tk window and all its descendants. +''' + + +import tkinter +from tkinter import tix + +TkdndVersion = None +ARM = 'arm' + +def _require(tkroot): + '''Internal function.''' + global TkdndVersion + try: + import os.path + import platform + + if platform.system()=="Darwin": + tkdnd_platform_rep = "osx_arm" if platform.processor() == ARM or ARM in platform.platform() else "osx64" + elif platform.system()=="Linux": + tkdnd_platform_rep = "linux64" + elif platform.system()=="Windows": + tkdnd_platform_rep = "win64" + else: + raise RuntimeError('Plaform not supported.') + + module_path = os.path.join(os.path.dirname(__file__), 'tkdnd', tkdnd_platform_rep) + tkroot.tk.call('lappend', 'auto_path', module_path) + TkdndVersion = tkroot.tk.call('package', 'require', 'tkdnd') + except tkinter.TclError: + raise RuntimeError('Unable to load tkdnd library.') + return TkdndVersion + +class DnDEvent: + """Internal class. + Container for the properties of a drag-and-drop event, similar to a + normal tkinter.Event. + An instance of the DnDEvent class has the following attributes: + action (string) + actions (tuple) + button (int) + code (string) + codes (tuple) + commonsourcetypes (tuple) + commontargettypes (tuple) + data (string) + name (string) + types (tuple) + modifiers (tuple) + supportedsourcetypes (tuple) + sourcetypes (tuple) + type (string) + supportedtargettypes (tuple) + widget (widget instance) + x_root (int) + y_root (int) + Depending on the type of DnD event however, not all attributes may be set. + """ + pass + +class DnDWrapper: + '''Internal class.''' + # some of the percent substitutions need to be enclosed in braces + # so we can use splitlist() to convert them into tuples + _subst_format_dnd = ('%A', '%a', '%b', '%C', '%c', '%CST', + '%CTT', '%D', '%e', '%L', '%m', '%ST', + '%T', '%t', '%TT', '%W', '%X', '%Y') + _subst_format_str_dnd = " ".join(_subst_format_dnd) + #print('_subst_format_dnd: ', _subst_format_dnd) + tkinter.BaseWidget._subst_format_dnd = _subst_format_dnd + tkinter.BaseWidget._subst_format_str_dnd = _subst_format_str_dnd + + def _substitute_dnd(self, *args): + """Internal function.""" + if len(args) != len(self._subst_format_dnd): + return args + def getint_event(s): + try: + return int(s) + except ValueError: + return s + def splitlist_event(s): + try: + return self.tk.splitlist(s) + except ValueError: + return s + # valid percent substitutions for DnD event types + # (tested with tkdnd-2.8 on debian jessie): + # <> : %W, %X, %Y %e, %t + # <> : %A, %W, %e + # <> : all except : %D (always empty) + # <> : all except %D (always empty) + # <> :all except %D (always empty) + # <> : all + A, a, b, C, c, CST, CTT, D, e, L, m, ST, T, t, TT, W, X, Y = args + ev = DnDEvent() + ev.action = A + ev.actions = splitlist_event(a) + ev.button = getint_event(b) + ev.code = C + ev.codes = splitlist_event(c) + ev.commonsourcetypes = splitlist_event(CST) + ev.commontargettypes = splitlist_event(CTT) + ev.data = D + ev.name = e + ev.types = splitlist_event(L) + ev.modifiers = splitlist_event(m) + ev.supportedsourcetypes = splitlist_event(ST) + ev.sourcetypes = splitlist_event(t) + ev.type = T + ev.supportedtargettypes = splitlist_event(TT) + try: + ev.widget = self.nametowidget(W) + except KeyError: + ev.widget = W + ev.x_root = getint_event(X) + ev.y_root = getint_event(Y) + + + + return (ev,) + tkinter.BaseWidget._substitute_dnd = _substitute_dnd + + def _dnd_bind(self, what, sequence, func, add, needcleanup=True): + """Internal function.""" + if isinstance(func, str): + self.tk.call(what + (sequence, func)) + elif func: + funcid = self._register(func, self._substitute_dnd, needcleanup) + # FIXME: why doesn't the "return 'break'" mechanism work here?? + #cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', + # funcid, self._subst_format_str_dnd)) + cmd = '%s%s %s' %(add and '+' or '', funcid, + self._subst_format_str_dnd) + self.tk.call(what + (sequence, cmd)) + return funcid + elif sequence: + return self.tk.call(what + (sequence,)) + else: + return self.tk.splitlist(self.tk.call(what)) + tkinter.BaseWidget._dnd_bind = _dnd_bind + + def dnd_bind(self, sequence=None, func=None, add=None): + '''Bind to this widget at drag and drop event SEQUENCE a call + to function FUNC. + SEQUENCE may be one of the following: + <>, <>, <>, <>, + <>, <>, <> . + The callbacks for the > events, with the exception of + <>, should always return an action (i.e. one of COPY, + MOVE, LINK, ASK or PRIVATE). + The callback for the <> event must return a tuple + containing three elements: the drop action(s) supported by the + drag source, the format type(s) that the data can be dropped as and + finally the data that shall be dropped. Each of these three elements + may be a tuple of strings or a single string.''' + return self._dnd_bind(('bind', self._w), sequence, func, add) + tkinter.BaseWidget.dnd_bind = dnd_bind + + def drag_source_register(self, button=None, *dndtypes): + '''This command will register SELF as a drag source. + A drag source is a widget than can start a drag action. This command + can be executed multiple times on a widget. + When SELF is registered as a drag source, optional DNDTYPES can be + provided. These DNDTYPES will be provided during a drag action, and + it can contain platform independent or platform specific types. + Platform independent are DND_Text for dropping text portions and + DND_Files for dropping a list of files (which can contain one or + multiple files) on SELF. However, these types are + indicative/informative. SELF can initiate a drag action with even a + different type list. Finally, button is the mouse button that will be + used for starting the drag action. It can have any of the values 1 + (left mouse button), 2 (middle mouse button - wheel) and 3 + (right mouse button). If button is not specified, it defaults to 1.''' + # hack to fix a design bug from the first version + if button is None: + button = 1 + else: + try: + button = int(button) + except ValueError: + # no button defined, button is actually + # something like DND_TEXT + dndtypes = (button,) + dndtypes + button = 1 + self.tk.call( + 'tkdnd::drag_source', 'register', self._w, dndtypes, button) + tkinter.BaseWidget.drag_source_register = drag_source_register + + def drag_source_unregister(self): + '''This command will stop SELF from being a drag source. Thus, window + will stop receiving events related to drag operations. It is an error + to use this command for a window that has not been registered as a + drag source with drag_source_register().''' + self.tk.call('tkdnd::drag_source', 'unregister', self._w) + tkinter.BaseWidget.drag_source_unregister = drag_source_unregister + + def drop_target_register(self, *dndtypes): + '''This command will register SELF as a drop target. A drop target is + a widget than can accept a drop action. This command can be executed + multiple times on a widget. When SELF is registered as a drop target, + optional DNDTYPES can be provided. These types list can contain one or + more types that SELF will accept during a drop action, and it can + contain platform independent or platform specific types. Platform + independent are DND_Text for dropping text portions and DND_Files for + dropping a list of files (which can contain one or multiple files) on + SELF.''' + self.tk.call('tkdnd::drop_target', 'register', self._w, dndtypes) + tkinter.BaseWidget.drop_target_register = drop_target_register + + def drop_target_unregister(self): + '''This command will stop SELF from being a drop target. Thus, SELF + will stop receiving events related to drop operations. It is an error + to use this command for a window that has not been registered as a + drop target with drop_target_register().''' + self.tk.call('tkdnd::drop_target', 'unregister', self._w) + tkinter.BaseWidget.drop_target_unregister = drop_target_unregister + + def platform_independent_types(self, *dndtypes): + '''This command will accept a list of types that can contain platform + independnent or platform specific types. A new list will be returned, + where each platform specific type in DNDTYPES will be substituted by + one or more platform independent types. Thus, the returned list may + have more elements than DNDTYPES.''' + return self.tk.split(self.tk.call( + 'tkdnd::platform_independent_types', dndtypes)) + tkinter.BaseWidget.platform_independent_types = platform_independent_types + + def platform_specific_types(self, *dndtypes): + '''This command will accept a list of types that can contain platform + independnent or platform specific types. A new list will be returned, + where each platform independent type in DNDTYPES will be substituted + by one or more platform specific types. Thus, the returned list may + have more elements than DNDTYPES.''' + return self.tk.split(self.tk.call( + 'tkdnd::platform_specific_types', dndtypes)) + tkinter.BaseWidget.platform_specific_types = platform_specific_types + + def get_dropfile_tempdir(self): + '''This command will return the temporary directory used by TkDND for + storing temporary files. When the package is loaded, this temporary + directory will be initialised to a proper directory according to the + operating system. This default initial value can be changed to be the + value of the following environmental variables: + TKDND_TEMP_DIR, TEMP, TMP.''' + return self.tk.call('tkdnd::GetDropFileTempDirectory') + tkinter.BaseWidget.get_dropfile_tempdir = get_dropfile_tempdir + + def set_dropfile_tempdir(self, tempdir): + '''This command will change the temporary directory used by TkDND for + storing temporary files to TEMPDIR.''' + self.tk.call('tkdnd::SetDropFileTempDirectory', tempdir) + tkinter.BaseWidget.set_dropfile_tempdir = set_dropfile_tempdir + +####################################################################### +#### The main window classes that enable Drag & Drop for #### +#### themselves and all their descendant widgets: #### +####################################################################### + +class Tk(tkinter.Tk, DnDWrapper): + '''Creates a new instance of a tkinter.Tk() window; all methods of the + DnDWrapper class apply to this window and all its descendants.''' + def __init__(self, *args, **kw): + tkinter.Tk.__init__(self, *args, **kw) + self.TkdndVersion = _require(self) + +class TixTk(tix.Tk, DnDWrapper): + '''Creates a new instance of a tix.Tk() window; all methods of the + DnDWrapper class apply to this window and all its descendants.''' + def __init__(self, *args, **kw): + tix.Tk.__init__(self, *args, **kw) + self.TkdndVersion = _require(self) diff --git a/gui_data/tkinterdnd2/__init__.py b/gui_data/tkinterdnd2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..17f037dd669b966490d32d0fb218dfe75b187713 --- /dev/null +++ b/gui_data/tkinterdnd2/__init__.py @@ -0,0 +1,25 @@ +# dnd actions +PRIVATE = 'private' +NONE = 'none' +ASK = 'ask' +COPY = 'copy' +MOVE = 'move' +LINK = 'link' +REFUSE_DROP = 'refuse_drop' + +# dnd types +DND_TEXT = 'DND_Text' +DND_FILES = 'DND_Files' +DND_ALL = '*' +CF_UNICODETEXT = 'CF_UNICODETEXT' +CF_TEXT = 'CF_TEXT' +CF_HDROP = 'CF_HDROP' + +FileGroupDescriptor = 'FileGroupDescriptor - FileContents'# ?? +FileGroupDescriptorW = 'FileGroupDescriptorW - FileContents'# ?? + +from . import TkinterDnD +from .TkinterDnD import Tk +from .TkinterDnD import TixTk + + diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/libtkdnd2.9.2.so b/gui_data/tkinterdnd2/tkdnd/linux64/libtkdnd2.9.2.so new file mode 100644 index 0000000000000000000000000000000000000000..03dbd1bb1f3ed549879f17db070a3d3b6f42538c Binary files /dev/null and b/gui_data/tkinterdnd2/tkdnd/linux64/libtkdnd2.9.2.so differ diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/pkgIndex.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/pkgIndex.tcl new file mode 100644 index 0000000000000000000000000000000000000000..9edcc8f2b4049c40b38f59c18de7b8525f3d7246 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/pkgIndex.tcl @@ -0,0 +1,10 @@ +# +# Tcl package index file +# +package ifneeded tkdnd 2.9.2 \ + "source \{$dir/tkdnd.tcl\} ; \ + tkdnd::initialise \{$dir\} libtkdnd2.9.2.so tkdnd" + +package ifneeded tkdnd::utils 2.9.2 \ + "source \{$dir/tkdnd_utils.tcl\} ; \ + package provide tkdnd::utils 2.9.2" diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd.tcl new file mode 100644 index 0000000000000000000000000000000000000000..12d1dd289de6b78e83922a1b1653ef6165dc70db --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd.tcl @@ -0,0 +1,469 @@ +# +# tkdnd.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require Tk + +namespace eval ::tkdnd { + variable _topw ".drag" + variable _tabops + variable _state + variable _x0 + variable _y0 + variable _platform_namespace + variable _drop_file_temp_dir + variable _auto_update 1 + variable _dx 3 ;# The difference in pixels before a drag is initiated. + variable _dy 3 ;# The difference in pixels before a drag is initiated. + + variable _windowingsystem + + bind TkDND_Drag1 {tkdnd::_begin_drag press 1 %W %s %X %Y %x %y} + bind TkDND_Drag1 {tkdnd::_begin_drag motion 1 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag press 2 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag motion 2 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag press 3 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag motion 3 %W %s %X %Y %x %y} + + # ---------------------------------------------------------------------------- + # Command tkdnd::initialise: Initialise the TkDND package. + # ---------------------------------------------------------------------------- + proc initialise { dir PKG_LIB_FILE PACKAGE_NAME} { + variable _platform_namespace + variable _drop_file_temp_dir + variable _windowingsystem + global env + + switch [tk windowingsystem] { + x11 { + set _windowingsystem x11 + } + win32 - + windows { + set _windowingsystem windows + } + aqua { + set _windowingsystem aqua + } + default { + error "unknown Tk windowing system" + } + } + + ## Get User's home directory: We try to locate the proper path from a set of + ## environmental variables... + foreach var {HOME HOMEPATH USERPROFILE ALLUSERSPROFILE APPDATA} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)]} { + set UserHomeDir $env($var) + break + } + } + } + + ## Should use [tk windowingsystem] instead of tcl platform array: + ## OS X returns "unix," but that's not useful because it has its own + ## windowing system, aqua + ## Under windows we have to also combine HOMEDRIVE & HOMEPATH... + if {![info exists UserHomeDir] && + [string equal $_windowingsystem windows] && + [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { + if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { + set UserHomeDir $env(HOMEDRIVE)$env(HOMEPATH) + } + } + ## Have we located the needed path? + if {![info exists UserHomeDir]} { + set UserHomeDir [pwd] + } + set UserHomeDir [file normalize $UserHomeDir] + + ## Try to locate a temporary directory... + foreach var {TKDND_TEMP_DIR TEMP TMP} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)] && [file writable $env($var)]} { + set _drop_file_temp_dir $env($var) + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + foreach _dir [list "$UserHomeDir/Local Settings/Temp" \ + "$UserHomeDir/AppData/Local/Temp" \ + /tmp \ + C:/WINDOWS/Temp C:/Temp C:/tmp \ + D:/WINDOWS/Temp D:/Temp D:/tmp] { + if {[file isdirectory $_dir] && [file writable $_dir]} { + set _drop_file_temp_dir $_dir + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + set _drop_file_temp_dir $UserHomeDir + } + set _drop_file_temp_dir [file native $_drop_file_temp_dir] + + source $dir/tkdnd_generic.tcl + switch $_windowingsystem { + x11 { + source $dir/tkdnd_unix.tcl + set _platform_namespace xdnd + } + win32 - + windows { + source $dir/tkdnd_windows.tcl + set _platform_namespace olednd + } + aqua { + source $dir/tkdnd_macosx.tcl + set _platform_namespace macdnd + } + default { + error "unknown Tk windowing system" + } + } + load $dir/$PKG_LIB_FILE $PACKAGE_NAME + source $dir/tkdnd_compat.tcl + ${_platform_namespace}::initialise + };# initialise + + proc GetDropFileTempDirectory { } { + variable _drop_file_temp_dir + return $_drop_file_temp_dir + } + proc SetDropFileTempDirectory { dir } { + variable _drop_file_temp_dir + set _drop_file_temp_dir $dir + } + +};# namespace ::tkdnd + +# ---------------------------------------------------------------------------- +# Command tkdnd::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::drag_source { mode path { types {} } { event 1 } + { tagprefix TkDND_Drag } } { + set tags [bindtags $path] + set idx [lsearch $tags ${tagprefix}$event] + switch -- $mode { + register { + if { $idx != -1 } { + ## No need to do anything! + # bindtags $path [lreplace $tags $idx $idx ${tagprefix}$event] + } else { + bindtags $path [linsert $tags 1 ${tagprefix}$event] + } + _drag_source_update_types $path $types + } + unregister { + if { $idx != -1 } { + bindtags $path [lreplace $tags $idx $idx] + } + } + } +};# tkdnd::drag_source + +proc ::tkdnd::_drag_source_update_types { path types } { + set types [platform_specific_types $types] + set old_types [bind $path <>] + foreach type $types { + if {[lsearch $old_types $type] < 0} {lappend old_types $type} + } + bind $path <> $old_types +};# ::tkdnd::_drag_source_update_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::drop_target { mode path { types {} } } { + variable _windowingsystem + set types [platform_specific_types $types] + switch -- $mode { + register { + switch $_windowingsystem { + x11 { + _register_types $path [winfo toplevel $path] $types + } + win32 - + windows { + _RegisterDragDrop $path + bind $path {+ tkdnd::_RevokeDragDrop %W} + } + aqua { + macdnd::registerdragwidget [winfo toplevel $path] $types + } + default { + error "unknown Tk windowing system" + } + } + set old_types [bind $path <>] + set new_types {} + foreach type $types { + if {[lsearch -exact $old_types $type] < 0} {lappend new_types $type} + } + if {[llength $new_types]} { + bind $path <> [concat $old_types $new_types] + } + } + unregister { + switch $_windowingsystem { + x11 { + } + win32 - + windows { + _RevokeDragDrop $path + } + aqua { + error todo + } + default { + error "unknown Tk windowing system" + } + } + bind $path <> {} + } + } +};# tkdnd::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_begin_drag { event button source state X Y x y } { + variable _x0 + variable _y0 + variable _state + + switch -- $event { + press { + set _x0 $X + set _y0 $Y + set _state "press" + } + motion { + if { ![info exists _state] } { + # This is just extra protection. There seem to be + # rare cases where the motion comes before the press. + return + } + if { [string equal $_state "press"] } { + variable _dx + variable _dy + if { abs($_x0-$X) > ${_dx} || abs($_y0-$Y) > ${_dy} } { + set _state "done" + _init_drag $button $source $state $X $Y $x $y + } + } + } + } +};# tkdnd::_begin_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_init_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_init_drag { button source state rootX rootY X Y } { + # Call the <> binding. + set cmd [bind $source <>] + # puts "CMD: $cmd" + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y \ + %S $state %e <> %A \{\} %% % \ + %t [bind $source <>]] $cmd] + set code [catch {uplevel \#0 $cmd} info options] + # puts "CODE: $code ---- $info" + switch -exact -- $code { + 0 {} + 3 - 4 { + # FRINK: nocheck + return + } + default { + return -options $options $info + } + } + + set len [llength $info] + if {$len == 3} { + foreach { actions types _data } $info { break } + set types [platform_specific_types $types] + set data [list] + foreach type $types { + lappend data $_data + } + unset _data + } elseif {$len == 2} { + foreach { actions _data } $info { break } + set data [list]; set types [list] + foreach {t d} $_data { + foreach t [platform_specific_types $t] { + lappend types $t; lappend data $d + } + } + unset _data t d + } else { + if {$len == 1 && [string equal [lindex $actions 0] "refuse_drop"]} { + return + } + error "not enough items in the result of the <>\ + event binding. Either 2 or 3 items are expected. The command + executed was: \"$cmd\"\nResult was: \"$info\"" + } + set action refuse_drop + variable _windowingsystem + # puts "Source: \"$source\"" + # puts "Types: \"[join $types {", "}]\"" + # puts "Actions: \"[join $actions {", "}]\"" + # puts "Button: \"$button\"" + # puts "Data: \"[string range $data 0 100]\"" + switch $_windowingsystem { + x11 { + set action [xdnd::_dodragdrop $source $actions $types $data $button] + } + win32 - + windows { + set action [_DoDragDrop $source $actions $types $data $button] + } + aqua { + set action [macdnd::dodragdrop $source $actions $types $data $button] + } + default { + error "unknown Tk windowing system" + } + } + ## Call _end_drag to notify the widget of the result of the drag + ## operation... + _end_drag $button $source {} $action {} $data {} $state $rootX $rootY $X $Y + } +};# tkdnd::_init_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_end_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_end_drag { button source target action type data result + state rootX rootY X Y } { + set rootX 0 + set rootY 0 + # Call the <> binding. + set cmd [bind $source <>] + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y %% % \ + %S $state %e <> %A \{$action\}] $cmd] + set info [uplevel \#0 $cmd] + # if { $info != "" } { + # variable _windowingsystem + # foreach { actions types data } $info { break } + # set types [platform_specific_types $types] + # switch $_windowingsystem { + # x11 { + # error "dragging from Tk widgets not yet supported" + # } + # win32 - + # windows { + # set action [_DoDragDrop $source $actions $types $data $button] + # } + # aqua { + # macdnd::dodragdrop $source $actions $types $data + # } + # default { + # error "unknown Tk windowing system" + # } + # } + # ## Call _end_drag to notify the widget of the result of the drag + # ## operation... + # _end_drag $button $source {} $action {} $data {} $state $rootX $rootY + # } + } +};# tkdnd::_end_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_types $types +}; # tkdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_type $type +}; # tkdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_type $type +}; # tkdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::bytes_to_string +# ---------------------------------------------------------------------------- +proc ::tkdnd::bytes_to_string { bytes } { + set string {} + foreach byte $bytes { + append string [binary format c $byte] + } + return $string +};# tkdnd::bytes_to_string + +# ---------------------------------------------------------------------------- +# Command tkdnd::urn_unquote +# ---------------------------------------------------------------------------- +proc ::tkdnd::urn_unquote {url} { + set result "" + set start 0 + while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { + foreach {first last} $match break + append result [string range $url $start [expr {$first - 1}]] + append result [format %c 0x[string range $url [incr first] $last]] + set start [incr last] + } + append result [string range $url $start end] + return [encoding convertfrom utf-8 $result] +};# tkdnd::urn_unquote diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_compat.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_compat.tcl new file mode 100644 index 0000000000000000000000000000000000000000..efc96f7bb2fe74a9bafd1e79681c275c8ea0f8fc --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_compat.tcl @@ -0,0 +1,160 @@ +# +# tkdnd_compat.tcl -- +# +# This file implements some utility procedures, to support older versions +# of the TkDND package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval compat { + +};# namespace compat + +# ---------------------------------------------------------------------------- +# Command ::dnd +# ---------------------------------------------------------------------------- +proc ::dnd {method window args} { + switch $method { + bindtarget { + switch [llength $args] { + 0 {return [tkdnd::compat::bindtarget0 $window]} + 1 {return [tkdnd::compat::bindtarget1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindtarget2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindtarget3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + 4 {return [tkdnd::compat::bindtarget4 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2] [lindex $args 3]]} + } + } + cleartarget { + return [tkdnd::compat::cleartarget $window] + } + bindsource { + switch [llength $args] { + 0 {return [tkdnd::compat::bindsource0 $window]} + 1 {return [tkdnd::compat::bindsource1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindsource2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindsource3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + } + } + clearsource { + return [tkdnd::compat::clearsource $window] + } + drag { + return [tkdnd::_init_drag 1 $window "press" 0 0 0 0] + } + } + error "invalid number of arguments!" +};# ::dnd + +# ---------------------------------------------------------------------------- +# Command compat::bindtarget +# ---------------------------------------------------------------------------- +proc compat::bindtarget0 {window} { + return [bind $window <>] +};# compat::bindtarget0 + +proc compat::bindtarget1 {window type} { + return [bindtarget2 $window $type ] +};# compat::bindtarget1 + +proc compat::bindtarget2 {window type event} { + switch $event { + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + } +};# compat::bindtarget2 + +proc compat::bindtarget3 {window type event script} { + set type [normalise_type $type] + ::tkdnd::drop_target register $window [list $type] + switch $event { + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + } +};# compat::bindtarget3 + +proc compat::bindtarget4 {window type event script priority} { + return [bindtarget3 $window $type $event $script] +};# compat::bindtarget4 + +proc compat::normalise_type { type } { + switch $type { + text/plain - + {text/plain;charset=UTF-8} - + Text {return DND_Text} + text/uri-list - + Files {return DND_Files} + default {return $type} + } +};# compat::normalise_type + +# ---------------------------------------------------------------------------- +# Command compat::bindsource +# ---------------------------------------------------------------------------- +proc compat::bindsource0 {window} { + return [bind $window <>] +};# compat::bindsource0 + +proc compat::bindsource1 {window type} { + return [bindsource2 $window $type ] +};# compat::bindsource1 + +proc compat::bindsource2 {window type script} { + set type [normalise_type $type] + ::tkdnd::drag_source register $window $type + bind $window <> "list {copy} {%t} \[$script\]" +};# compat::bindsource2 + +proc compat::bindsource3 {window type script priority} { + return [bindsource2 $window $type $script] +};# compat::bindsource3 + +# ---------------------------------------------------------------------------- +# Command compat::cleartarget +# ---------------------------------------------------------------------------- +proc compat::cleartarget {window} { +};# compat::cleartarget + +# ---------------------------------------------------------------------------- +# Command compat::clearsource +# ---------------------------------------------------------------------------- +proc compat::clearsource {window} { +};# compat::clearsource diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_generic.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_generic.tcl new file mode 100644 index 0000000000000000000000000000000000000000..698b464fc68e8a2e0e681f5bac32c4c63338f2c3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_generic.tcl @@ -0,0 +1,520 @@ +# +# tkdnd_generic.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval generic { + variable _types {} + variable _typelist {} + variable _codelist {} + variable _actionlist {} + variable _pressedkeys {} + variable _action {} + variable _common_drag_source_types {} + variable _common_drop_target_types {} + variable _drag_source {} + variable _drop_target {} + + variable _last_mouse_root_x 0 + variable _last_mouse_root_y 0 + + variable _tkdnd2platform + variable _platform2tkdnd + + proc debug {msg} { + puts $msg + };# debug + + proc initialise { } { + };# initialise + + proc initialise_platform_to_tkdnd_types { types } { + variable _platform2tkdnd + variable _tkdnd2platform + set _platform2tkdnd [dict create {*}$types] + set _tkdnd2platform [dict create] + foreach type [dict keys $_platform2tkdnd] { + dict lappend _tkdnd2platform [dict get $_platform2tkdnd $type] $type + } + };# initialise_platform_to_tkdnd_types + + proc initialise_tkdnd_to_platform_types { types } { + variable _tkdnd2platform + set _tkdnd2platform [dict create {*}$types] + };# initialise_tkdnd_to_platform_types + +};# namespace generic + +# ---------------------------------------------------------------------------- +# Command generic::HandleEnter +# ---------------------------------------------------------------------------- +proc generic::HandleEnter { drop_target drag_source typelist codelist + actionlist pressedkeys } { + variable _typelist; set _typelist $typelist + variable _pressedkeys; set _pressedkeys $pressedkeys + variable _action; set _action refuse_drop + variable _common_drag_source_types; set _common_drag_source_types {} + variable _common_drop_target_types; set _common_drop_target_types {} + variable _actionlist + variable _drag_source; set _drag_source $drag_source + variable _drop_target; set _drop_target {} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist + + variable _last_mouse_root_x; set _last_mouse_root_x 0 + variable _last_mouse_root_y; set _last_mouse_root_y 0 + # debug "\n===============================================================" + # debug "generic::HandleEnter: drop_target=$drop_target,\ + # drag_source=$drag_source,\ + # typelist=$typelist" + # debug "generic::HandleEnter: ACTION: default" + return default +};# generic::HandleEnter + +# ---------------------------------------------------------------------------- +# Command generic::HandlePosition +# ---------------------------------------------------------------------------- +proc generic::HandlePosition { drop_target drag_source pressedkeys + rootX rootY { time 0 } } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + # debug "generic::HandlePosition: drop_target=$drop_target,\ + # _drop_target=$_drop_target, rootX=$rootX, rootY=$rootY" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + # debug "generic::HandlePosition: no or empty _drag_source:\ + # return refuse_drop" + return refuse_drop + } + + if {$drag_source ne "" && $drag_source ne $_drag_source} { + debug "generic position event from unexpected source: $_drag_source\ + != $drag_source" + return refuse_drop + } + + set _pressedkeys $pressedkeys + + ## Does the new drop target support any of our new types? + # foreach {common_drag_source_types common_drop_target_types} \ + # [GetWindowCommonTypes $drop_target $_typelist] {break} + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [FindWindowWithCommonTypes $drop_target $_typelist] {break} + set data [GetDroppedData $time] + + # debug "\t($_drop_target) -> ($drop_target)" + if {$drop_target != $_drop_target} { + if {[string length $_drop_target]} { + ## Call the <> event. + # debug "\t<> on $_drop_target" + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + uplevel \#0 $cmd + } + } + set _drop_target $drop_target + set _action refuse_drop + + if {[llength $common_drag_source_types]} { + set _action [lindex $_actionlist 0] + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + ## Drop target supports at least one type. Send a <>. + # puts "<> -> $drop_target" + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + focus $drop_target + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + } + } + } + + set _drop_target {} + if {[llength $common_drag_source_types]} { + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <>. + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + # Return values: copy, move, link, ask, private, refuse_drop, default + # debug "generic::HandlePosition: ACTION: $_action" + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandlePosition + +# ---------------------------------------------------------------------------- +# Command generic::HandleLeave +# ---------------------------------------------------------------------------- +proc generic::HandleLeave { } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + if {![info exists _drop_target]} {set _drop_target {}} + # debug "generic::HandleLeave: _drop_target=$_drop_target" + if {[info exists _drop_target] && [string length $_drop_target]} { + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target \ + %X $_last_mouse_root_x %Y $_last_mouse_root_y \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + foreach var {_types _typelist _actionlist _pressedkeys _action + _common_drag_source_types _common_drop_target_types + _drag_source _drop_target} { + set $var {} + } +};# generic::HandleLeave + +# ---------------------------------------------------------------------------- +# Command generic::HandleDrop +# ---------------------------------------------------------------------------- +proc generic::HandleDrop {drop_target drag_source pressedkeys rootX rootY time } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + set _pressedkeys $pressedkeys + + # puts "generic::HandleDrop: $time" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + return refuse_drop + } + if {![info exists _drop_target] && ![string length $_drop_target]} { + return refuse_drop + } + if {![llength $_common_drag_source_types]} {return refuse_drop} + ## Get the dropped data. + set data [GetDroppedData $time] + ## Try to select the most specific <> event. + foreach type [concat $_common_drag_source_types $_common_drop_target_types] { + set type [platform_independent_type $type] + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action + } + } + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandleDrop + +# ---------------------------------------------------------------------------- +# Command generic::GetWindowCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetWindowCommonTypes { win typelist } { + set types [bind $win <>] + # debug ">> Accepted types: $win $_types" + set common_drag_source_types {} + set common_drop_target_types {} + if {[llength $types]} { + ## Examine the drop target types, to find at least one match with the drag + ## source types... + set supported_types [supported_types $typelist] + foreach type $types { + foreach matched [lsearch -glob -all -inline $supported_types $type] { + ## Drop target supports this type. + lappend common_drag_source_types $matched + lappend common_drop_target_types $type + } + } + } + list $common_drag_source_types $common_drop_target_types +};# generic::GetWindowCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::FindWindowWithCommonTypes +# ---------------------------------------------------------------------------- +proc generic::FindWindowWithCommonTypes { win typelist } { + set toplevel [winfo toplevel $win] + while {![string equal $win $toplevel]} { + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + set win [winfo parent $win] + } + ## We have reached the toplevel, which may be also a target (SF Bug #30) + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + return { {} {} {} } +};# generic::FindWindowWithCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDroppedData +# ---------------------------------------------------------------------------- +proc generic::GetDroppedData { time } { + variable _dropped_data + return $_dropped_data +};# generic::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::SetDroppedData +# ---------------------------------------------------------------------------- +proc generic::SetDroppedData { data } { + variable _dropped_data + set _dropped_data $data +};# generic::SetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSource +# ---------------------------------------------------------------------------- +proc generic::GetDragSource { } { + variable _drag_source + return $_drag_source +};# generic::GetDragSource + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTarget +# ---------------------------------------------------------------------------- +proc generic::GetDropTarget { } { + variable _drop_target + return $_drop_target +};# generic::GetDropTarget + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDragSourceCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTargetCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDropTargetCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDropTargetCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_types +# ---------------------------------------------------------------------------- +proc generic::platform_specific_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_specific_type $type]] + } + return $new_types +}; # generic::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_type +# ---------------------------------------------------------------------------- +proc generic::platform_specific_type { type } { + variable _tkdnd2platform + if {[dict exists $_tkdnd2platform $type]} { + return [dict get $_tkdnd2platform $type] + } + list $type +}; # generic::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_independent_type $type]] + } + return $new_types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_type +# ---------------------------------------------------------------------------- +proc generic::platform_independent_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return [dict get $_platform2tkdnd $type] + } + return $type +}; # generic::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command generic::supported_types +# ---------------------------------------------------------------------------- +proc generic::supported_types { types } { + set new_types {} + foreach type $types { + if {[supported_type $type]} {lappend new_types $type} + } + return $new_types +}; # generic::supported_types + +# ---------------------------------------------------------------------------- +# Command generic::supported_type +# ---------------------------------------------------------------------------- +proc generic::supported_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return 1 + } + return 0 +}; # generic::supported_type diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_macosx.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_macosx.tcl new file mode 100644 index 0000000000000000000000000000000000000000..307f6da2e94286d01dc9e068fffebe46de3c43f3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_macosx.tcl @@ -0,0 +1,144 @@ +# +# tkdnd_macosx.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. + +# This software is copyrighted by: +# Georgios Petasis, Athens, Greece. +# e-mail: petasisg@yahoo.gr, petasis@iit.demokritos.gr +# +# Mac portions (c) 2009 Kevin Walzer/WordTech Communications LLC, +# kw@codebykevin.com +# +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +#basic API for Mac Drag and Drop + +#two data types supported: strings and file paths + +#two commands at C level: ::tkdnd::macdnd::registerdragwidget, ::tkdnd::macdnd::unregisterdragwidget + +#data retrieval mechanism: text or file paths are copied from drag clipboard to system clipboard and retrieved via [clipboard get]; array of file paths is converted to single tab-separated string, can be split into Tcl list + +if {[tk windowingsystem] eq "aqua" && "AppKit" ni [winfo server .]} { + error {TkAqua Cocoa required} +} + +namespace eval macdnd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + NSPasteboardTypeString DND_Text \ + NSFilenamesPboardType DND_Files \ + NSPasteboardTypeHTML DND_HTML \ + ] + };# initialise + +};# namespace macdnd + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleEnter +# ---------------------------------------------------------------------------- +proc macdnd::HandleEnter { path drag_source typelist { data {} } } { + variable _pressedkeys + variable _actionlist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# macdnd::HandleEnter + +# ---------------------------------------------------------------------------- +# Command macdnd::HandlePosition +# ---------------------------------------------------------------------------- +proc macdnd::HandlePosition { drop_target rootX rootY {drag_source {}} } { + variable _pressedkeys + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# macdnd::HandlePosition + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleLeave +# ---------------------------------------------------------------------------- +proc macdnd::HandleLeave { args } { + ::tkdnd::generic::HandleLeave +};# macdnd::HandleLeave + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleDrop +# ---------------------------------------------------------------------------- +proc macdnd::HandleDrop { drop_target data args } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y 0 +};# macdnd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command macdnd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc macdnd::GetDragSourceCommonTypes { } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# macdnd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # macdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # macdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # macdnd::platform_independent_type diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_unix.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_unix.tcl new file mode 100644 index 0000000000000000000000000000000000000000..56d17c4db718274df4b3b7a14f0d8e055a1002b6 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_unix.tcl @@ -0,0 +1,810 @@ +# +# tkdnd_unix.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval xdnd { + variable _dragging 0 + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + text/plain\;charset=utf-8 DND_Text \ + UTF8_STRING DND_Text \ + text/plain DND_Text \ + STRING DND_Text \ + TEXT DND_Text \ + COMPOUND_TEXT DND_Text \ + text/uri-list DND_Files \ + text/html\;charset=utf-8 DND_HTML \ + text/html DND_HTML \ + application/x-color DND_Color \ + ] + };# initialise + +};# namespace xdnd + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndEnter { path drag_source typelist time { data {} } } { + variable _pressedkeys + variable _actionlist + variable _typelist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + set _typelist $typelist + # puts "xdnd::HandleXdndEnter: $time" + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# xdnd::HandleXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndPosition { drop_target rootX rootY time {drag_source {}} } { + variable _pressedkeys + variable _typelist + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + # puts "xdnd::HandleXdndPosition: $time" + ## Get the dropped data... + catch { + ::tkdnd::generic::SetDroppedData [GetPositionData $drop_target $_typelist $time] + } + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# xdnd::HandleXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndLeave { } { + ::tkdnd::generic::HandleLeave +};# xdnd::HandleXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndDrop { time } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData [GetDroppedData \ + [::tkdnd::generic::GetDragSource] [::tkdnd::generic::GetDropTarget] \ + [::tkdnd::generic::GetDragSourceCommonTypes] $time] + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y $time +};# xdnd::HandleXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::GetPositionData +# ---------------------------------------------------------------------------- +proc xdnd::GetPositionData { drop_target typelist time } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + GetDroppedData [::tkdnd::generic::GetDragSource] $drop_target \ + $common_drag_source_types $time +};# xdnd::GetPositionData + +# ---------------------------------------------------------------------------- +# Command xdnd::GetDroppedData +# ---------------------------------------------------------------------------- +proc xdnd::GetDroppedData { _drag_source _drop_target _common_drag_source_types time } { + if {![llength $_common_drag_source_types]} { + error "no common data types between the drag source and drop target widgets" + } + ## Is drag source in this application? + if {[catch {winfo pathname -displayof $_drop_target $_drag_source} p]} { + set _use_tk_selection 0 + } else { + set _use_tk_selection 1 + } + foreach type $_common_drag_source_types { + # puts "TYPE: $type ($_drop_target)" + # _get_selection $_drop_target $time $type + if {$_use_tk_selection} { + if {![catch { + selection get -displayof $_drop_target -selection XdndSelection \ + -type $type + } result options]} { + return [normalise_data $type $result] + } + } else { + # puts "_selection_get -displayof $_drop_target -selection XdndSelection \ + # -type $type -time $time" + #after 100 [list focus -force $_drop_target] + #after 50 [list raise [winfo toplevel $_drop_target]] + if {![catch { + _selection_get -displayof $_drop_target -selection XdndSelection \ + -type $type -time $time + } result options]} { + return [normalise_data $type $result] + } + } + } + return -options $options $result +};# xdnd::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # xdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # xdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # xdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command xdnd::_normalise_data +# ---------------------------------------------------------------------------- +proc xdnd::normalise_data { type data } { + # Tk knows how to interpret the following types: + # STRING, TEXT, COMPOUND_TEXT + # UTF8_STRING + # Else, it returns a list of 8 or 32 bit numbers... + switch -glob $type { + STRING - UTF8_STRING - TEXT - COMPOUND_TEXT {return $data} + text/html { + if {[catch { + encoding convertfrom unicode $data + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/html\;charset=utf-8 - + text/plain\;charset=utf-8 - + text/plain { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/uri-list* { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + ## Get rid of \r\n + set string [string trim [string map {\r\n \n} $string]] + set files {} + foreach quoted_file [split $string] { + set file [tkdnd::urn_unquote $quoted_file] + switch -glob $file { + \#* {} + file://* {lappend files [string range $file 7 end]} + ftp://* - + https://* - + http://* {lappend files $quoted_file} + default {lappend files $file} + } + } + return $files + } + application/x-color { + return $data + } + text/x-moz-url - + application/q-iconlist - + default {return $data} + } +}; # xdnd::normalise_data + +############################################################################# +## +## XDND drag implementation +## +############################################################################# + +# ---------------------------------------------------------------------------- +# Command xdnd::_selection_ownership_lost +# ---------------------------------------------------------------------------- +proc xdnd::_selection_ownership_lost {} { + variable _dragging + set _dragging 0 +};# _selection_ownership_lost + +# ---------------------------------------------------------------------------- +# Command xdnd::_dodragdrop +# ---------------------------------------------------------------------------- +proc xdnd::_dodragdrop { source actions types data button } { + variable _dragging + + # puts "xdnd::_dodragdrop: source: $source, actions: $actions, types: $types,\ + # data: \"$data\", button: $button" + if {$_dragging} { + ## We are in the middle of another drag operation... + error "another drag operation in progress" + } + + variable _dodragdrop_drag_source $source + variable _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_proxy 0 + variable _dodragdrop_actions $actions + variable _dodragdrop_action_descriptions $actions + variable _dodragdrop_actions_len [llength $actions] + variable _dodragdrop_types $types + variable _dodragdrop_types_len [llength $types] + variable _dodragdrop_data $data + variable _dodragdrop_transfer_data {} + variable _dodragdrop_button $button + variable _dodragdrop_time 0 + variable _dodragdrop_default_action refuse_drop + variable _dodragdrop_waiting_status 0 + variable _dodragdrop_drop_target_accepts_drop 0 + variable _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_current_cursor $_dodragdrop_default_action + variable _dodragdrop_drop_occured 0 + variable _dodragdrop_selection_requestor 0 + + ## + ## If we have more than 3 types, the property XdndTypeList must be set on + ## the drag source widget... + ## + if {$_dodragdrop_types_len > 3} { + _announce_type_list $_dodragdrop_drag_source $_dodragdrop_types + } + + ## + ## Announce the actions & their descriptions on the XdndActionList & + ## XdndActionDescription properties... + ## + _announce_action_list $_dodragdrop_drag_source $_dodragdrop_actions \ + $_dodragdrop_action_descriptions + + ## + ## Arrange selection handlers for our drag source, and all the supported types + ## + registerSelectionHandler $source $types + + ## + ## Step 1: When a drag begins, the source takes ownership of XdndSelection. + ## + selection own -command ::tkdnd::xdnd::_selection_ownership_lost \ + -selection XdndSelection $source + set _dragging 1 + + ## Grab the mouse pointer... + _grab_pointer $source $_dodragdrop_default_action + + ## Register our generic event handler... + # The generic event callback will report events by modifying variable + # ::xdnd::_dodragdrop_event: a dict with event information will be set as + # the value of the variable... + _register_generic_event_handler + + ## Set a timeout for debugging purposes... + # after 60000 {set ::tkdnd::xdnd::_dragging 0} + + tkwait variable ::tkdnd::xdnd::_dragging + _SendXdndLeave + + set _dragging 0 + _ungrab_pointer $source + _unregister_generic_event_handler + catch {selection clear -selection XdndSelection} + unregisterSelectionHandler $source $types + return $_dodragdrop_drop_target_accepts_action +};# xdnd::_dodragdrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_process_drag_events +# ---------------------------------------------------------------------------- +proc xdnd::_process_drag_events {event} { + # The return value from proc is normally 0. A non-zero return value indicates + # that the event is not to be handled further; that is, proc has done all + # processing that is to be allowed for the event + variable _dragging + if {!$_dragging} {return 0} + # puts $event + + variable _dodragdrop_time + set time [dict get $event time] + set type [dict get $event type] + if {$time < $_dodragdrop_time && ![string equal $type SelectionRequest]} { + return 0 + } + set _dodragdrop_time $time + + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_default_action + switch $type { + MotionNotify { + set rootx [dict get $event x_root] + set rooty [dict get $event y_root] + set window [_find_drop_target_window $_dodragdrop_drag_source \ + $rootx $rooty] + if {[string length $window]} { + ## Examine the modifiers to suggest an action... + set _dodragdrop_default_action [_default_action $event] + ## Is it a Tk widget? + # set path [winfo containing $rootx $rooty] + # puts "Window under mouse: $window ($path)" + if {$_dodragdrop_drop_target != $window} { + ## Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + ## Is there a proxy? If not, _find_drop_target_proxy returns the + ## target window, so we always get a valid "proxy". + set proxy [_find_drop_target_proxy $_dodragdrop_drag_source $window] + ## Send XdndEnter to $window + _SendXdndEnter $window $proxy + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } else { + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } + } else { + ## No window under the mouse. Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + } + } + ButtonPress { + } + ButtonRelease { + variable _dodragdrop_button + set button [dict get $event button] + if {$button == $_dodragdrop_button} { + ## The button that initiated the drag was released. Trigger drop... + _SendXdndDrop + } + return 1 + } + KeyPress { + } + KeyRelease { + set keysym [dict get $event keysym] + switch $keysym { + Escape { + ## The user has pressed escape. Abort... + if {$_dragging} {set _dragging 0} + } + } + } + SelectionRequest { + variable _dodragdrop_selection_requestor + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + set _dodragdrop_selection_requestor [dict get $event requestor] + set _dodragdrop_selection_property [dict get $event property] + set _dodragdrop_selection_selection [dict get $event selection] + set _dodragdrop_selection_target [dict get $event target] + set _dodragdrop_selection_time $time + return 0 + } + default { + return 0 + } + } + return 0 +};# _process_drag_events + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndEnter {window proxy} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_types + variable _dodragdrop_waiting_status + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_target > 0} _SendXdndLeave + if {$_dodragdrop_drop_occured} return + set _dodragdrop_drop_target $window + set _dodragdrop_drop_target_proxy $proxy + set _dodragdrop_waiting_status 0 + if {$_dodragdrop_drop_target < 1} return + # puts "XdndEnter: $_dodragdrop_drop_target $_dodragdrop_drop_target_proxy" + _send_XdndEnter $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $_dodragdrop_types +};# xdnd::_SendXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndPosition {rootx rooty action} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_waiting_status + ## Arrange a new XdndPosition, to be send periodically... + variable _dodragdrop_xdnd_position_heartbeat + catch {after cancel $_dodragdrop_xdnd_position_heartbeat} + set _dodragdrop_xdnd_position_heartbeat [after 200 \ + [list ::tkdnd::xdnd::_SendXdndPosition $rootx $rooty $action]] + if {$_dodragdrop_waiting_status} {return} + # puts "XdndPosition: $_dodragdrop_drop_target $rootx $rooty $action" + _send_XdndPosition $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $rootx $rooty $action + set _dodragdrop_waiting_status 1 +};# xdnd::_SendXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndStatus +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndStatus {event} { + variable _dodragdrop_drop_target + variable _dodragdrop_waiting_status + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_waiting_status 0 + foreach key {target accept want_position action x y w h} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor + # puts "XdndStatus: $event" +};# xdnd::_HandleXdndStatus + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndFinished +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndFinished {event} { + variable _dodragdrop_xdnd_finished_event_after_id + catch {after cancel $_dodragdrop_xdnd_finished_event_after_id} + set _dodragdrop_xdnd_finished_event_after_id {} + variable _dodragdrop_drop_target + set _dodragdrop_drop_target 0 + variable _dragging + if {$_dragging} {set _dragging 0} + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + if {[dict size $event]} { + foreach key {target accept action} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + } else { + set _dodragdrop_drop_target_accepts_drop 0 + } + if {!$_dodragdrop_drop_target_accepts_drop} { + set _dodragdrop_drop_target_accepts_action refuse_drop + } + # puts "XdndFinished: $event" +};# xdnd::_HandleXdndFinished + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndLeave {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_target_proxy + # puts "XdndLeave: $_dodragdrop_drop_target" + _send_XdndLeave $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy + set _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_drop_target_accepts_drop 0 + set _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor +};# xdnd::_SendXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndDrop {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} { + ## The mouse has been released over a widget that does not accept drops. + _HandleXdndFinished {} + return + } + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} {return} + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + set _dodragdrop_drop_occured 1 + _update_cursor clock + + if {!$_dodragdrop_drop_target_accepts_drop} { + _SendXdndLeave + _HandleXdndFinished {} + return + } + # puts "XdndDrop: $_dodragdrop_drop_target" + variable _dodragdrop_drop_timestamp + set _dodragdrop_drop_timestamp [_send_XdndDrop \ + $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy] + set _dodragdrop_drop_target 0 + # puts "XdndDrop: $_dodragdrop_drop_target" + ## Arrange a timeout for receiving XdndFinished... + variable _dodragdrop_xdnd_finished_event_after_id + set _dodragdrop_xdnd_finished_event_after_id \ + [after 10000 [list ::tkdnd::xdnd::_HandleXdndFinished {}]] +};# xdnd::_SendXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_update_cursor +# ---------------------------------------------------------------------------- +proc xdnd::_update_cursor { {cursor {}}} { + # puts "_update_cursor $cursor" + variable _dodragdrop_current_cursor + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + if {![string length $cursor]} { + set cursor refuse_drop + if {$_dodragdrop_drop_target_accepts_drop} { + set cursor $_dodragdrop_drop_target_accepts_action + } + } + if {![string equal $cursor $_dodragdrop_current_cursor]} { + _set_pointer_cursor $_dodragdrop_drag_source $cursor + set _dodragdrop_current_cursor $cursor + } +};# xdnd::_update_cursor + +# ---------------------------------------------------------------------------- +# Command xdnd::_default_action +# ---------------------------------------------------------------------------- +proc xdnd::_default_action {event} { + variable _dodragdrop_actions + variable _dodragdrop_actions_len + if {$_dodragdrop_actions_len == 1} {return [lindex $_dodragdrop_actions 0]} + + set alt [dict get $event Alt] + set shift [dict get $event Shift] + set control [dict get $event Control] + + if {$shift && $control && [lsearch $_dodragdrop_actions link] != -1} { + return link + } elseif {$control && [lsearch $_dodragdrop_actions copy] != -1} { + return copy + } elseif {$shift && [lsearch $_dodragdrop_actions move] != -1} { + return move + } elseif {$alt && [lsearch $_dodragdrop_actions link] != -1} { + return link + } + return default +};# xdnd::_default_action + +# ---------------------------------------------------------------------------- +# Command xdnd::getFormatForType +# ---------------------------------------------------------------------------- +proc xdnd::getFormatForType {type} { + switch -glob [string tolower $type] { + text/plain\;charset=utf-8 - + text/html\;charset=utf-8 - + utf8_string {set format UTF8_STRING} + text/html - + text/plain - + string - + text - + compound_text {set format STRING} + text/uri-list* {set format UTF8_STRING} + application/x-color {set format $type} + default {set format $type} + } + return $format +};# xdnd::getFormatForType + +# ---------------------------------------------------------------------------- +# Command xdnd::registerSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::registerSelectionHandler {source types} { + foreach type $types { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source [list ::tkdnd::xdnd::_SendData $type] + } +};# xdnd::registerSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::unregisterSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::unregisterSelectionHandler {source types} { + foreach type $types { + catch { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source {} + } + } +};# xdnd::unregisterSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::_convert_to_unsigned +# ---------------------------------------------------------------------------- +proc xdnd::_convert_to_unsigned {data format} { + switch $format { + 8 { set mask 0xff } + 16 { set mask 0xffff } + 32 { set mask 0xffffff } + default {error "unsupported format $format"} + } + ## Convert signed integer into unsigned... + set d [list] + foreach num $data { + lappend d [expr { $num & $mask }] + } + return $d +};# xdnd::_convert_to_unsigned + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendData +# ---------------------------------------------------------------------------- +proc xdnd::_SendData {type offset bytes args} { + variable _dodragdrop_drag_source + variable _dodragdrop_types + variable _dodragdrop_data + variable _dodragdrop_transfer_data + + ## The variable _dodragdrop_data contains a list of data, one for each + ## type in the _dodragdrop_types variable. We have to search types, and find + ## the corresponding entry in the _dodragdrop_data list. + set index [lsearch $_dodragdrop_types $type] + if {$index < 0} { + error "unable to locate data suitable for type \"$type\"" + } + set typed_data [lindex $_dodragdrop_data $index] + set format 8 + if {$offset == 0} { + ## Prepare the data to be transferred... + switch -glob $type { + text/plain* - UTF8_STRING - STRING - TEXT - COMPOUND_TEXT { + binary scan [encoding convertto utf-8 $typed_data] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + text/uri-list* { + set files [list] + foreach file $typed_data { + switch -glob $file { + *://* {lappend files $file} + default {lappend files file://$file} + } + } + binary scan [encoding convertto utf-8 "[join $files \r\n]\r\n"] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + application/x-color { + set format 16 + ## Try to understand the provided data: we accept a standard Tk colour, + ## or a list of 3 values (red green blue) or a list of 4 values + ## (red green blue opacity). + switch [llength $typed_data] { + 1 { set color [winfo rgb $_dodragdrop_drag_source $typed_data] + lappend color 65535 } + 3 { set color $typed_data; lappend color 65535 } + 4 { set color $typed_data } + default {error "unknown color data: \"$typed_data\""} + } + ## Convert the 4 elements into 16 bit values... + set _dodragdrop_transfer_data [list] + foreach c $color { + lappend _dodragdrop_transfer_data [format 0x%04X $c] + } + } + default { + set format 32 + binary scan $typed_data c* _dodragdrop_transfer_data + } + } + } + + ## + ## Data has been split into bytes. Count the bytes requested, and return them + ## + set data [lrange $_dodragdrop_transfer_data $offset [expr {$offset+$bytes-1}]] + switch $format { + 8 { + set data [encoding convertfrom utf-8 [binary format c* $data]] + } + 16 { + variable _dodragdrop_selection_requestor + if {$_dodragdrop_selection_requestor} { + ## Tk selection cannot process this format (only 8 & 32 supported). + ## Call our XChangeProperty... + set numItems [llength $data] + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + XChangeProperty $_dodragdrop_drag_source \ + $_dodragdrop_selection_requestor \ + $_dodragdrop_selection_property \ + $_dodragdrop_selection_target \ + $format \ + $_dodragdrop_selection_time \ + $data $numItems + return -code break + } + } + 32 { + } + default { + error "unsupported format $format" + } + } + # puts "SendData: $type $offset $bytes $args ($typed_data)" + # puts " $data" + return $data +};# xdnd::_SendData diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_utils.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_utils.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ee961ddb1ca29b383496111eadc2ccdce7776b08 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_utils.tcl @@ -0,0 +1,252 @@ +# +# tkdnd_utils.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require tkdnd +namespace eval ::tkdnd { + namespace eval utils { + };# namespace ::tkdnd::utils + namespace eval text { + variable _drag_tag tkdnd::drag::selection::tag + variable _state {} + variable _drag_source_widget {} + variable _drop_target_widget {} + variable _now_dragging 0 + };# namespace ::tkdnd::text +};# namespace ::tkdnd + +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag clear 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag motion 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_TextAutoScan %W %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag reset 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag clear 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag motion 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag reset 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag clear 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag motion 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag reset 3 %W %s %X %Y %x %y} + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drag_source { mode path { types DND_Text } { event 1 } { tagprefix TkDND_Drag_Text } { tag sel } } { + switch -exact -- $mode { + register { + $path tag bind $tag \ + "tkdnd::text::_begin_drag press ${event} %W %s %X %Y %x %y" + ## Set a binding to the widget, to put selection as data... + bind $path <> "::tkdnd::text::DragInitCmd $path {%t} $tag" + ## Set a binding to the widget, to remove selection if action is move... + bind $path <> "::tkdnd::text::DragEndCmd $path %A $tag" + } + unregister { + $path tag bind $tag {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drag_source $mode $path $types $event $tagprefix +};# ::tkdnd::text::drag_source + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drop_target { mode path { types DND_Text } } { + switch -exact -- $mode { + register { + bind $path <> "::tkdnd::text::DropPosition $path %X %Y %A %a %m" + bind $path <> "::tkdnd::text::Drop $path %D %X %Y %A %a %m" + } + unregister { + bind $path <> {} + bind $path <> {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drop_target $mode $path $types +};# ::tkdnd::text::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragInitCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragInitCmd { path { types DND_Text } { tag sel } { actions { copy move } } } { + ## Save the selection indices... + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget $path + set _drop_target_widget {} + _save_selection $path $tag + list $actions $types [$path get $tag.first $tag.last] +};# ::tkdnd::text::DragInitCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragEndCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragEndCmd { path action { tag sel } } { + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget {} + set _drop_target_widget {} + _restore_selection $path $tag + switch -exact -- $action { + move { + ## Delete the original selected text... + variable _selection_first + variable _selection_last + $path delete $_selection_first $_selection_last + } + } +};# ::tkdnd::text::DragEndCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DropPosition +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DropPosition { path X Y action actions keys} { + variable _drag_source_widget + variable _drop_target_widget + set _drop_target_widget $path + ## This check is primitive, a more accurate one is needed! + if {$path eq $_drag_source_widget} { + ## This is a drag within the same widget! Set action to move... + if {"move" in $actions} {set action move} + } + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y; update + return $action +};# ::tkdnd::text::DropPosition + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::Drop +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::Drop { path data X Y action actions keys } { + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y + $path insert [$path index insert] $data + return $action +};# ::tkdnd::text::Drop + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_save_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_save_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + variable _selection_tag $tag + set _selection_first [$path index $tag.first] + set _selection_last [$path index $tag.last] + $path tag add $_drag_tag $_selection_first $_selection_last + $path tag configure $_drag_tag \ + -background [$path tag cget $tag -background] \ + -foreground [$path tag cget $tag -foreground] +};# tkdnd::text::_save_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_restore_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_restore_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + $path tag delete $_drag_tag + $path tag remove $tag 0.0 end + #$path tag add $tag $_selection_first $_selection_last +};# tkdnd::text::_restore_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_begin_drag { event button source state X Y x y } { + variable _drop_target_widget + variable _state + # puts "::tkdnd::text::_begin_drag $event $button $source $state $X $Y $x $y" + + switch -exact -- $event { + clear { + switch -exact -- $_state { + press { + ## Do not execute other bindings, as they will erase selection... + return -code break + } + } + set _state clear + } + motion { + variable _now_dragging + if {$_now_dragging} {return -code break} + if { [string equal $_state "press"] } { + variable _x0; variable _y0 + if { abs($_x0-$X) > ${::tkdnd::_dx} || abs($_y0-$Y) > ${::tkdnd::_dy} } { + set _state "done" + set _drop_target_widget {} + set _now_dragging 1 + set code [catch { + ::tkdnd::_init_drag $button $source $state $X $Y $x $y + } info options] + set _drop_target_widget {} + set _now_dragging 0 + if {$code != 0} { + ## Something strange occurred... + return -options $options $info + } + } + return -code break + } + set _state clear + } + press { + variable _x0; variable _y0 + set _x0 $X + set _y0 $Y + set _state "press" + } + reset { + set _state {} + } + } + if {$source eq $_drop_target_widget} {return -code break} + return -code continue +};# tkdnd::text::_begin_drag + +proc tkdnd::text::_TextAutoScan {w x y} { + variable _now_dragging + if {$_now_dragging} {return -code break} + return -code continue +};# tkdnd::text::_TextAutoScan diff --git a/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_windows.tcl b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_windows.tcl new file mode 100644 index 0000000000000000000000000000000000000000..a1d01f3a2c438eaf3f676437d4d4ba89b3ba64f0 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/linux64/tkdnd_windows.tcl @@ -0,0 +1,167 @@ +# +# tkdnd_windows.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval olednd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + CF_UNICODETEXT DND_Text \ + CF_TEXT DND_Text \ + CF_HDROP DND_Files \ + UniformResourceLocator DND_URL \ + CF_HTML DND_HTML \ + {HTML Format} DND_HTML \ + CF_RTF DND_RTF \ + CF_RTFTEXT DND_RTF \ + {Rich Text Format} DND_RTF \ + ] + # FileGroupDescriptorW DND_Files \ + # FileGroupDescriptor DND_Files \ + + ## Mapping from TkDND types to platform types... + ::tkdnd::generic::initialise_tkdnd_to_platform_types [list \ + DND_Text {CF_UNICODETEXT CF_TEXT} \ + DND_Files {CF_HDROP} \ + DND_URL {UniformResourceLocator UniformResourceLocatorW} \ + DND_HTML {CF_HTML {HTML Format}} \ + DND_RTF {CF_RTF CF_RTFTEXT {Rich Text Format}} \ + ] + };# initialise + +};# namespace olednd + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragEnter +# ---------------------------------------------------------------------------- +proc olednd::HandleDragEnter { drop_target typelist actionlist pressedkeys + rootX rootY codelist { data {} } } { + ::tkdnd::generic::SetDroppedData $data + focus $drop_target + ::tkdnd::generic::HandleEnter $drop_target 0 $typelist \ + $codelist $actionlist $pressedkeys + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragEnter + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragOver +# ---------------------------------------------------------------------------- +proc olednd::HandleDragOver { drop_target pressedkeys rootX rootY } { + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragOver + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragLeave +# ---------------------------------------------------------------------------- +proc olednd::HandleDragLeave { drop_target } { + ::tkdnd::generic::HandleLeave + if {$::tkdnd::_auto_update} {update idletasks} +};# olednd::HandleDragLeave + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDrop +# ---------------------------------------------------------------------------- +proc olednd::HandleDrop { drop_target pressedkeys rootX rootY type data } { + ::tkdnd::generic::SetDroppedData [normalise_data $type $data] + set action [::tkdnd::generic::HandleDrop $drop_target {} \ + $pressedkeys $rootX $rootY 0] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command olednd::GetDataType +# ---------------------------------------------------------------------------- +proc olednd::GetDataType { drop_target typelist } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + lindex $common_drag_source_types 0 +};# olednd::GetDataType + +# ---------------------------------------------------------------------------- +# Command olednd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc olednd::GetDragSourceCommonTypes { drop_target } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# olednd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_types +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # olednd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_type +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # olednd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_independent_type +# ---------------------------------------------------------------------------- +proc olednd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # olednd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command olednd::normalise_data +# ---------------------------------------------------------------------------- +proc olednd::normalise_data { type data } { + switch [lindex [::tkdnd::generic::platform_independent_type $type] 0] { + DND_Text {return $data} + DND_Files {return $data} + DND_HTML {return [encoding convertfrom utf-8 $data]} + default {return $data} + } +}; # olednd::normalise_data diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/libtkdnd2.9.2.dylib b/gui_data/tkinterdnd2/tkdnd/osx64/libtkdnd2.9.2.dylib new file mode 100644 index 0000000000000000000000000000000000000000..2f511c423e109f80e7511c768cfb81d16a1cd65a Binary files /dev/null and b/gui_data/tkinterdnd2/tkdnd/osx64/libtkdnd2.9.2.dylib differ diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/pkgIndex.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/pkgIndex.tcl new file mode 100644 index 0000000000000000000000000000000000000000..d46e91c53205b270f70be7c124dc7715ba93bed9 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/pkgIndex.tcl @@ -0,0 +1,10 @@ +# +# Tcl package index file +# +package ifneeded tkdnd 2.9.2 \ + "source \{$dir/tkdnd.tcl\} ; \ + tkdnd::initialise \{$dir\} libtkdnd2.9.2.dylib tkdnd" + +package ifneeded tkdnd::utils 2.9.2 \ + "source \{$dir/tkdnd_utils.tcl\} ; \ + package provide tkdnd::utils 2.9.2" diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd.tcl new file mode 100644 index 0000000000000000000000000000000000000000..12d1dd289de6b78e83922a1b1653ef6165dc70db --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd.tcl @@ -0,0 +1,469 @@ +# +# tkdnd.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require Tk + +namespace eval ::tkdnd { + variable _topw ".drag" + variable _tabops + variable _state + variable _x0 + variable _y0 + variable _platform_namespace + variable _drop_file_temp_dir + variable _auto_update 1 + variable _dx 3 ;# The difference in pixels before a drag is initiated. + variable _dy 3 ;# The difference in pixels before a drag is initiated. + + variable _windowingsystem + + bind TkDND_Drag1 {tkdnd::_begin_drag press 1 %W %s %X %Y %x %y} + bind TkDND_Drag1 {tkdnd::_begin_drag motion 1 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag press 2 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag motion 2 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag press 3 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag motion 3 %W %s %X %Y %x %y} + + # ---------------------------------------------------------------------------- + # Command tkdnd::initialise: Initialise the TkDND package. + # ---------------------------------------------------------------------------- + proc initialise { dir PKG_LIB_FILE PACKAGE_NAME} { + variable _platform_namespace + variable _drop_file_temp_dir + variable _windowingsystem + global env + + switch [tk windowingsystem] { + x11 { + set _windowingsystem x11 + } + win32 - + windows { + set _windowingsystem windows + } + aqua { + set _windowingsystem aqua + } + default { + error "unknown Tk windowing system" + } + } + + ## Get User's home directory: We try to locate the proper path from a set of + ## environmental variables... + foreach var {HOME HOMEPATH USERPROFILE ALLUSERSPROFILE APPDATA} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)]} { + set UserHomeDir $env($var) + break + } + } + } + + ## Should use [tk windowingsystem] instead of tcl platform array: + ## OS X returns "unix," but that's not useful because it has its own + ## windowing system, aqua + ## Under windows we have to also combine HOMEDRIVE & HOMEPATH... + if {![info exists UserHomeDir] && + [string equal $_windowingsystem windows] && + [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { + if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { + set UserHomeDir $env(HOMEDRIVE)$env(HOMEPATH) + } + } + ## Have we located the needed path? + if {![info exists UserHomeDir]} { + set UserHomeDir [pwd] + } + set UserHomeDir [file normalize $UserHomeDir] + + ## Try to locate a temporary directory... + foreach var {TKDND_TEMP_DIR TEMP TMP} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)] && [file writable $env($var)]} { + set _drop_file_temp_dir $env($var) + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + foreach _dir [list "$UserHomeDir/Local Settings/Temp" \ + "$UserHomeDir/AppData/Local/Temp" \ + /tmp \ + C:/WINDOWS/Temp C:/Temp C:/tmp \ + D:/WINDOWS/Temp D:/Temp D:/tmp] { + if {[file isdirectory $_dir] && [file writable $_dir]} { + set _drop_file_temp_dir $_dir + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + set _drop_file_temp_dir $UserHomeDir + } + set _drop_file_temp_dir [file native $_drop_file_temp_dir] + + source $dir/tkdnd_generic.tcl + switch $_windowingsystem { + x11 { + source $dir/tkdnd_unix.tcl + set _platform_namespace xdnd + } + win32 - + windows { + source $dir/tkdnd_windows.tcl + set _platform_namespace olednd + } + aqua { + source $dir/tkdnd_macosx.tcl + set _platform_namespace macdnd + } + default { + error "unknown Tk windowing system" + } + } + load $dir/$PKG_LIB_FILE $PACKAGE_NAME + source $dir/tkdnd_compat.tcl + ${_platform_namespace}::initialise + };# initialise + + proc GetDropFileTempDirectory { } { + variable _drop_file_temp_dir + return $_drop_file_temp_dir + } + proc SetDropFileTempDirectory { dir } { + variable _drop_file_temp_dir + set _drop_file_temp_dir $dir + } + +};# namespace ::tkdnd + +# ---------------------------------------------------------------------------- +# Command tkdnd::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::drag_source { mode path { types {} } { event 1 } + { tagprefix TkDND_Drag } } { + set tags [bindtags $path] + set idx [lsearch $tags ${tagprefix}$event] + switch -- $mode { + register { + if { $idx != -1 } { + ## No need to do anything! + # bindtags $path [lreplace $tags $idx $idx ${tagprefix}$event] + } else { + bindtags $path [linsert $tags 1 ${tagprefix}$event] + } + _drag_source_update_types $path $types + } + unregister { + if { $idx != -1 } { + bindtags $path [lreplace $tags $idx $idx] + } + } + } +};# tkdnd::drag_source + +proc ::tkdnd::_drag_source_update_types { path types } { + set types [platform_specific_types $types] + set old_types [bind $path <>] + foreach type $types { + if {[lsearch $old_types $type] < 0} {lappend old_types $type} + } + bind $path <> $old_types +};# ::tkdnd::_drag_source_update_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::drop_target { mode path { types {} } } { + variable _windowingsystem + set types [platform_specific_types $types] + switch -- $mode { + register { + switch $_windowingsystem { + x11 { + _register_types $path [winfo toplevel $path] $types + } + win32 - + windows { + _RegisterDragDrop $path + bind $path {+ tkdnd::_RevokeDragDrop %W} + } + aqua { + macdnd::registerdragwidget [winfo toplevel $path] $types + } + default { + error "unknown Tk windowing system" + } + } + set old_types [bind $path <>] + set new_types {} + foreach type $types { + if {[lsearch -exact $old_types $type] < 0} {lappend new_types $type} + } + if {[llength $new_types]} { + bind $path <> [concat $old_types $new_types] + } + } + unregister { + switch $_windowingsystem { + x11 { + } + win32 - + windows { + _RevokeDragDrop $path + } + aqua { + error todo + } + default { + error "unknown Tk windowing system" + } + } + bind $path <> {} + } + } +};# tkdnd::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_begin_drag { event button source state X Y x y } { + variable _x0 + variable _y0 + variable _state + + switch -- $event { + press { + set _x0 $X + set _y0 $Y + set _state "press" + } + motion { + if { ![info exists _state] } { + # This is just extra protection. There seem to be + # rare cases where the motion comes before the press. + return + } + if { [string equal $_state "press"] } { + variable _dx + variable _dy + if { abs($_x0-$X) > ${_dx} || abs($_y0-$Y) > ${_dy} } { + set _state "done" + _init_drag $button $source $state $X $Y $x $y + } + } + } + } +};# tkdnd::_begin_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_init_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_init_drag { button source state rootX rootY X Y } { + # Call the <> binding. + set cmd [bind $source <>] + # puts "CMD: $cmd" + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y \ + %S $state %e <> %A \{\} %% % \ + %t [bind $source <>]] $cmd] + set code [catch {uplevel \#0 $cmd} info options] + # puts "CODE: $code ---- $info" + switch -exact -- $code { + 0 {} + 3 - 4 { + # FRINK: nocheck + return + } + default { + return -options $options $info + } + } + + set len [llength $info] + if {$len == 3} { + foreach { actions types _data } $info { break } + set types [platform_specific_types $types] + set data [list] + foreach type $types { + lappend data $_data + } + unset _data + } elseif {$len == 2} { + foreach { actions _data } $info { break } + set data [list]; set types [list] + foreach {t d} $_data { + foreach t [platform_specific_types $t] { + lappend types $t; lappend data $d + } + } + unset _data t d + } else { + if {$len == 1 && [string equal [lindex $actions 0] "refuse_drop"]} { + return + } + error "not enough items in the result of the <>\ + event binding. Either 2 or 3 items are expected. The command + executed was: \"$cmd\"\nResult was: \"$info\"" + } + set action refuse_drop + variable _windowingsystem + # puts "Source: \"$source\"" + # puts "Types: \"[join $types {", "}]\"" + # puts "Actions: \"[join $actions {", "}]\"" + # puts "Button: \"$button\"" + # puts "Data: \"[string range $data 0 100]\"" + switch $_windowingsystem { + x11 { + set action [xdnd::_dodragdrop $source $actions $types $data $button] + } + win32 - + windows { + set action [_DoDragDrop $source $actions $types $data $button] + } + aqua { + set action [macdnd::dodragdrop $source $actions $types $data $button] + } + default { + error "unknown Tk windowing system" + } + } + ## Call _end_drag to notify the widget of the result of the drag + ## operation... + _end_drag $button $source {} $action {} $data {} $state $rootX $rootY $X $Y + } +};# tkdnd::_init_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_end_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_end_drag { button source target action type data result + state rootX rootY X Y } { + set rootX 0 + set rootY 0 + # Call the <> binding. + set cmd [bind $source <>] + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y %% % \ + %S $state %e <> %A \{$action\}] $cmd] + set info [uplevel \#0 $cmd] + # if { $info != "" } { + # variable _windowingsystem + # foreach { actions types data } $info { break } + # set types [platform_specific_types $types] + # switch $_windowingsystem { + # x11 { + # error "dragging from Tk widgets not yet supported" + # } + # win32 - + # windows { + # set action [_DoDragDrop $source $actions $types $data $button] + # } + # aqua { + # macdnd::dodragdrop $source $actions $types $data + # } + # default { + # error "unknown Tk windowing system" + # } + # } + # ## Call _end_drag to notify the widget of the result of the drag + # ## operation... + # _end_drag $button $source {} $action {} $data {} $state $rootX $rootY + # } + } +};# tkdnd::_end_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_types $types +}; # tkdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_type $type +}; # tkdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_type $type +}; # tkdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::bytes_to_string +# ---------------------------------------------------------------------------- +proc ::tkdnd::bytes_to_string { bytes } { + set string {} + foreach byte $bytes { + append string [binary format c $byte] + } + return $string +};# tkdnd::bytes_to_string + +# ---------------------------------------------------------------------------- +# Command tkdnd::urn_unquote +# ---------------------------------------------------------------------------- +proc ::tkdnd::urn_unquote {url} { + set result "" + set start 0 + while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { + foreach {first last} $match break + append result [string range $url $start [expr {$first - 1}]] + append result [format %c 0x[string range $url [incr first] $last]] + set start [incr last] + } + append result [string range $url $start end] + return [encoding convertfrom utf-8 $result] +};# tkdnd::urn_unquote diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_compat.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_compat.tcl new file mode 100644 index 0000000000000000000000000000000000000000..efc96f7bb2fe74a9bafd1e79681c275c8ea0f8fc --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_compat.tcl @@ -0,0 +1,160 @@ +# +# tkdnd_compat.tcl -- +# +# This file implements some utility procedures, to support older versions +# of the TkDND package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval compat { + +};# namespace compat + +# ---------------------------------------------------------------------------- +# Command ::dnd +# ---------------------------------------------------------------------------- +proc ::dnd {method window args} { + switch $method { + bindtarget { + switch [llength $args] { + 0 {return [tkdnd::compat::bindtarget0 $window]} + 1 {return [tkdnd::compat::bindtarget1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindtarget2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindtarget3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + 4 {return [tkdnd::compat::bindtarget4 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2] [lindex $args 3]]} + } + } + cleartarget { + return [tkdnd::compat::cleartarget $window] + } + bindsource { + switch [llength $args] { + 0 {return [tkdnd::compat::bindsource0 $window]} + 1 {return [tkdnd::compat::bindsource1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindsource2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindsource3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + } + } + clearsource { + return [tkdnd::compat::clearsource $window] + } + drag { + return [tkdnd::_init_drag 1 $window "press" 0 0 0 0] + } + } + error "invalid number of arguments!" +};# ::dnd + +# ---------------------------------------------------------------------------- +# Command compat::bindtarget +# ---------------------------------------------------------------------------- +proc compat::bindtarget0 {window} { + return [bind $window <>] +};# compat::bindtarget0 + +proc compat::bindtarget1 {window type} { + return [bindtarget2 $window $type ] +};# compat::bindtarget1 + +proc compat::bindtarget2 {window type event} { + switch $event { + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + } +};# compat::bindtarget2 + +proc compat::bindtarget3 {window type event script} { + set type [normalise_type $type] + ::tkdnd::drop_target register $window [list $type] + switch $event { + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + } +};# compat::bindtarget3 + +proc compat::bindtarget4 {window type event script priority} { + return [bindtarget3 $window $type $event $script] +};# compat::bindtarget4 + +proc compat::normalise_type { type } { + switch $type { + text/plain - + {text/plain;charset=UTF-8} - + Text {return DND_Text} + text/uri-list - + Files {return DND_Files} + default {return $type} + } +};# compat::normalise_type + +# ---------------------------------------------------------------------------- +# Command compat::bindsource +# ---------------------------------------------------------------------------- +proc compat::bindsource0 {window} { + return [bind $window <>] +};# compat::bindsource0 + +proc compat::bindsource1 {window type} { + return [bindsource2 $window $type ] +};# compat::bindsource1 + +proc compat::bindsource2 {window type script} { + set type [normalise_type $type] + ::tkdnd::drag_source register $window $type + bind $window <> "list {copy} {%t} \[$script\]" +};# compat::bindsource2 + +proc compat::bindsource3 {window type script priority} { + return [bindsource2 $window $type $script] +};# compat::bindsource3 + +# ---------------------------------------------------------------------------- +# Command compat::cleartarget +# ---------------------------------------------------------------------------- +proc compat::cleartarget {window} { +};# compat::cleartarget + +# ---------------------------------------------------------------------------- +# Command compat::clearsource +# ---------------------------------------------------------------------------- +proc compat::clearsource {window} { +};# compat::clearsource diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_generic.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_generic.tcl new file mode 100644 index 0000000000000000000000000000000000000000..698b464fc68e8a2e0e681f5bac32c4c63338f2c3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_generic.tcl @@ -0,0 +1,520 @@ +# +# tkdnd_generic.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval generic { + variable _types {} + variable _typelist {} + variable _codelist {} + variable _actionlist {} + variable _pressedkeys {} + variable _action {} + variable _common_drag_source_types {} + variable _common_drop_target_types {} + variable _drag_source {} + variable _drop_target {} + + variable _last_mouse_root_x 0 + variable _last_mouse_root_y 0 + + variable _tkdnd2platform + variable _platform2tkdnd + + proc debug {msg} { + puts $msg + };# debug + + proc initialise { } { + };# initialise + + proc initialise_platform_to_tkdnd_types { types } { + variable _platform2tkdnd + variable _tkdnd2platform + set _platform2tkdnd [dict create {*}$types] + set _tkdnd2platform [dict create] + foreach type [dict keys $_platform2tkdnd] { + dict lappend _tkdnd2platform [dict get $_platform2tkdnd $type] $type + } + };# initialise_platform_to_tkdnd_types + + proc initialise_tkdnd_to_platform_types { types } { + variable _tkdnd2platform + set _tkdnd2platform [dict create {*}$types] + };# initialise_tkdnd_to_platform_types + +};# namespace generic + +# ---------------------------------------------------------------------------- +# Command generic::HandleEnter +# ---------------------------------------------------------------------------- +proc generic::HandleEnter { drop_target drag_source typelist codelist + actionlist pressedkeys } { + variable _typelist; set _typelist $typelist + variable _pressedkeys; set _pressedkeys $pressedkeys + variable _action; set _action refuse_drop + variable _common_drag_source_types; set _common_drag_source_types {} + variable _common_drop_target_types; set _common_drop_target_types {} + variable _actionlist + variable _drag_source; set _drag_source $drag_source + variable _drop_target; set _drop_target {} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist + + variable _last_mouse_root_x; set _last_mouse_root_x 0 + variable _last_mouse_root_y; set _last_mouse_root_y 0 + # debug "\n===============================================================" + # debug "generic::HandleEnter: drop_target=$drop_target,\ + # drag_source=$drag_source,\ + # typelist=$typelist" + # debug "generic::HandleEnter: ACTION: default" + return default +};# generic::HandleEnter + +# ---------------------------------------------------------------------------- +# Command generic::HandlePosition +# ---------------------------------------------------------------------------- +proc generic::HandlePosition { drop_target drag_source pressedkeys + rootX rootY { time 0 } } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + # debug "generic::HandlePosition: drop_target=$drop_target,\ + # _drop_target=$_drop_target, rootX=$rootX, rootY=$rootY" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + # debug "generic::HandlePosition: no or empty _drag_source:\ + # return refuse_drop" + return refuse_drop + } + + if {$drag_source ne "" && $drag_source ne $_drag_source} { + debug "generic position event from unexpected source: $_drag_source\ + != $drag_source" + return refuse_drop + } + + set _pressedkeys $pressedkeys + + ## Does the new drop target support any of our new types? + # foreach {common_drag_source_types common_drop_target_types} \ + # [GetWindowCommonTypes $drop_target $_typelist] {break} + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [FindWindowWithCommonTypes $drop_target $_typelist] {break} + set data [GetDroppedData $time] + + # debug "\t($_drop_target) -> ($drop_target)" + if {$drop_target != $_drop_target} { + if {[string length $_drop_target]} { + ## Call the <> event. + # debug "\t<> on $_drop_target" + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + uplevel \#0 $cmd + } + } + set _drop_target $drop_target + set _action refuse_drop + + if {[llength $common_drag_source_types]} { + set _action [lindex $_actionlist 0] + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + ## Drop target supports at least one type. Send a <>. + # puts "<> -> $drop_target" + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + focus $drop_target + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + } + } + } + + set _drop_target {} + if {[llength $common_drag_source_types]} { + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <>. + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + # Return values: copy, move, link, ask, private, refuse_drop, default + # debug "generic::HandlePosition: ACTION: $_action" + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandlePosition + +# ---------------------------------------------------------------------------- +# Command generic::HandleLeave +# ---------------------------------------------------------------------------- +proc generic::HandleLeave { } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + if {![info exists _drop_target]} {set _drop_target {}} + # debug "generic::HandleLeave: _drop_target=$_drop_target" + if {[info exists _drop_target] && [string length $_drop_target]} { + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target \ + %X $_last_mouse_root_x %Y $_last_mouse_root_y \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + foreach var {_types _typelist _actionlist _pressedkeys _action + _common_drag_source_types _common_drop_target_types + _drag_source _drop_target} { + set $var {} + } +};# generic::HandleLeave + +# ---------------------------------------------------------------------------- +# Command generic::HandleDrop +# ---------------------------------------------------------------------------- +proc generic::HandleDrop {drop_target drag_source pressedkeys rootX rootY time } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + set _pressedkeys $pressedkeys + + # puts "generic::HandleDrop: $time" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + return refuse_drop + } + if {![info exists _drop_target] && ![string length $_drop_target]} { + return refuse_drop + } + if {![llength $_common_drag_source_types]} {return refuse_drop} + ## Get the dropped data. + set data [GetDroppedData $time] + ## Try to select the most specific <> event. + foreach type [concat $_common_drag_source_types $_common_drop_target_types] { + set type [platform_independent_type $type] + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action + } + } + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandleDrop + +# ---------------------------------------------------------------------------- +# Command generic::GetWindowCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetWindowCommonTypes { win typelist } { + set types [bind $win <>] + # debug ">> Accepted types: $win $_types" + set common_drag_source_types {} + set common_drop_target_types {} + if {[llength $types]} { + ## Examine the drop target types, to find at least one match with the drag + ## source types... + set supported_types [supported_types $typelist] + foreach type $types { + foreach matched [lsearch -glob -all -inline $supported_types $type] { + ## Drop target supports this type. + lappend common_drag_source_types $matched + lappend common_drop_target_types $type + } + } + } + list $common_drag_source_types $common_drop_target_types +};# generic::GetWindowCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::FindWindowWithCommonTypes +# ---------------------------------------------------------------------------- +proc generic::FindWindowWithCommonTypes { win typelist } { + set toplevel [winfo toplevel $win] + while {![string equal $win $toplevel]} { + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + set win [winfo parent $win] + } + ## We have reached the toplevel, which may be also a target (SF Bug #30) + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + return { {} {} {} } +};# generic::FindWindowWithCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDroppedData +# ---------------------------------------------------------------------------- +proc generic::GetDroppedData { time } { + variable _dropped_data + return $_dropped_data +};# generic::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::SetDroppedData +# ---------------------------------------------------------------------------- +proc generic::SetDroppedData { data } { + variable _dropped_data + set _dropped_data $data +};# generic::SetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSource +# ---------------------------------------------------------------------------- +proc generic::GetDragSource { } { + variable _drag_source + return $_drag_source +};# generic::GetDragSource + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTarget +# ---------------------------------------------------------------------------- +proc generic::GetDropTarget { } { + variable _drop_target + return $_drop_target +};# generic::GetDropTarget + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDragSourceCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTargetCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDropTargetCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDropTargetCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_types +# ---------------------------------------------------------------------------- +proc generic::platform_specific_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_specific_type $type]] + } + return $new_types +}; # generic::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_type +# ---------------------------------------------------------------------------- +proc generic::platform_specific_type { type } { + variable _tkdnd2platform + if {[dict exists $_tkdnd2platform $type]} { + return [dict get $_tkdnd2platform $type] + } + list $type +}; # generic::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_independent_type $type]] + } + return $new_types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_type +# ---------------------------------------------------------------------------- +proc generic::platform_independent_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return [dict get $_platform2tkdnd $type] + } + return $type +}; # generic::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command generic::supported_types +# ---------------------------------------------------------------------------- +proc generic::supported_types { types } { + set new_types {} + foreach type $types { + if {[supported_type $type]} {lappend new_types $type} + } + return $new_types +}; # generic::supported_types + +# ---------------------------------------------------------------------------- +# Command generic::supported_type +# ---------------------------------------------------------------------------- +proc generic::supported_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return 1 + } + return 0 +}; # generic::supported_type diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_macosx.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_macosx.tcl new file mode 100644 index 0000000000000000000000000000000000000000..307f6da2e94286d01dc9e068fffebe46de3c43f3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_macosx.tcl @@ -0,0 +1,144 @@ +# +# tkdnd_macosx.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. + +# This software is copyrighted by: +# Georgios Petasis, Athens, Greece. +# e-mail: petasisg@yahoo.gr, petasis@iit.demokritos.gr +# +# Mac portions (c) 2009 Kevin Walzer/WordTech Communications LLC, +# kw@codebykevin.com +# +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +#basic API for Mac Drag and Drop + +#two data types supported: strings and file paths + +#two commands at C level: ::tkdnd::macdnd::registerdragwidget, ::tkdnd::macdnd::unregisterdragwidget + +#data retrieval mechanism: text or file paths are copied from drag clipboard to system clipboard and retrieved via [clipboard get]; array of file paths is converted to single tab-separated string, can be split into Tcl list + +if {[tk windowingsystem] eq "aqua" && "AppKit" ni [winfo server .]} { + error {TkAqua Cocoa required} +} + +namespace eval macdnd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + NSPasteboardTypeString DND_Text \ + NSFilenamesPboardType DND_Files \ + NSPasteboardTypeHTML DND_HTML \ + ] + };# initialise + +};# namespace macdnd + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleEnter +# ---------------------------------------------------------------------------- +proc macdnd::HandleEnter { path drag_source typelist { data {} } } { + variable _pressedkeys + variable _actionlist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# macdnd::HandleEnter + +# ---------------------------------------------------------------------------- +# Command macdnd::HandlePosition +# ---------------------------------------------------------------------------- +proc macdnd::HandlePosition { drop_target rootX rootY {drag_source {}} } { + variable _pressedkeys + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# macdnd::HandlePosition + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleLeave +# ---------------------------------------------------------------------------- +proc macdnd::HandleLeave { args } { + ::tkdnd::generic::HandleLeave +};# macdnd::HandleLeave + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleDrop +# ---------------------------------------------------------------------------- +proc macdnd::HandleDrop { drop_target data args } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y 0 +};# macdnd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command macdnd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc macdnd::GetDragSourceCommonTypes { } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# macdnd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # macdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # macdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # macdnd::platform_independent_type diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_unix.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_unix.tcl new file mode 100644 index 0000000000000000000000000000000000000000..56d17c4db718274df4b3b7a14f0d8e055a1002b6 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_unix.tcl @@ -0,0 +1,810 @@ +# +# tkdnd_unix.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval xdnd { + variable _dragging 0 + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + text/plain\;charset=utf-8 DND_Text \ + UTF8_STRING DND_Text \ + text/plain DND_Text \ + STRING DND_Text \ + TEXT DND_Text \ + COMPOUND_TEXT DND_Text \ + text/uri-list DND_Files \ + text/html\;charset=utf-8 DND_HTML \ + text/html DND_HTML \ + application/x-color DND_Color \ + ] + };# initialise + +};# namespace xdnd + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndEnter { path drag_source typelist time { data {} } } { + variable _pressedkeys + variable _actionlist + variable _typelist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + set _typelist $typelist + # puts "xdnd::HandleXdndEnter: $time" + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# xdnd::HandleXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndPosition { drop_target rootX rootY time {drag_source {}} } { + variable _pressedkeys + variable _typelist + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + # puts "xdnd::HandleXdndPosition: $time" + ## Get the dropped data... + catch { + ::tkdnd::generic::SetDroppedData [GetPositionData $drop_target $_typelist $time] + } + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# xdnd::HandleXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndLeave { } { + ::tkdnd::generic::HandleLeave +};# xdnd::HandleXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndDrop { time } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData [GetDroppedData \ + [::tkdnd::generic::GetDragSource] [::tkdnd::generic::GetDropTarget] \ + [::tkdnd::generic::GetDragSourceCommonTypes] $time] + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y $time +};# xdnd::HandleXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::GetPositionData +# ---------------------------------------------------------------------------- +proc xdnd::GetPositionData { drop_target typelist time } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + GetDroppedData [::tkdnd::generic::GetDragSource] $drop_target \ + $common_drag_source_types $time +};# xdnd::GetPositionData + +# ---------------------------------------------------------------------------- +# Command xdnd::GetDroppedData +# ---------------------------------------------------------------------------- +proc xdnd::GetDroppedData { _drag_source _drop_target _common_drag_source_types time } { + if {![llength $_common_drag_source_types]} { + error "no common data types between the drag source and drop target widgets" + } + ## Is drag source in this application? + if {[catch {winfo pathname -displayof $_drop_target $_drag_source} p]} { + set _use_tk_selection 0 + } else { + set _use_tk_selection 1 + } + foreach type $_common_drag_source_types { + # puts "TYPE: $type ($_drop_target)" + # _get_selection $_drop_target $time $type + if {$_use_tk_selection} { + if {![catch { + selection get -displayof $_drop_target -selection XdndSelection \ + -type $type + } result options]} { + return [normalise_data $type $result] + } + } else { + # puts "_selection_get -displayof $_drop_target -selection XdndSelection \ + # -type $type -time $time" + #after 100 [list focus -force $_drop_target] + #after 50 [list raise [winfo toplevel $_drop_target]] + if {![catch { + _selection_get -displayof $_drop_target -selection XdndSelection \ + -type $type -time $time + } result options]} { + return [normalise_data $type $result] + } + } + } + return -options $options $result +};# xdnd::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # xdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # xdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # xdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command xdnd::_normalise_data +# ---------------------------------------------------------------------------- +proc xdnd::normalise_data { type data } { + # Tk knows how to interpret the following types: + # STRING, TEXT, COMPOUND_TEXT + # UTF8_STRING + # Else, it returns a list of 8 or 32 bit numbers... + switch -glob $type { + STRING - UTF8_STRING - TEXT - COMPOUND_TEXT {return $data} + text/html { + if {[catch { + encoding convertfrom unicode $data + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/html\;charset=utf-8 - + text/plain\;charset=utf-8 - + text/plain { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/uri-list* { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + ## Get rid of \r\n + set string [string trim [string map {\r\n \n} $string]] + set files {} + foreach quoted_file [split $string] { + set file [tkdnd::urn_unquote $quoted_file] + switch -glob $file { + \#* {} + file://* {lappend files [string range $file 7 end]} + ftp://* - + https://* - + http://* {lappend files $quoted_file} + default {lappend files $file} + } + } + return $files + } + application/x-color { + return $data + } + text/x-moz-url - + application/q-iconlist - + default {return $data} + } +}; # xdnd::normalise_data + +############################################################################# +## +## XDND drag implementation +## +############################################################################# + +# ---------------------------------------------------------------------------- +# Command xdnd::_selection_ownership_lost +# ---------------------------------------------------------------------------- +proc xdnd::_selection_ownership_lost {} { + variable _dragging + set _dragging 0 +};# _selection_ownership_lost + +# ---------------------------------------------------------------------------- +# Command xdnd::_dodragdrop +# ---------------------------------------------------------------------------- +proc xdnd::_dodragdrop { source actions types data button } { + variable _dragging + + # puts "xdnd::_dodragdrop: source: $source, actions: $actions, types: $types,\ + # data: \"$data\", button: $button" + if {$_dragging} { + ## We are in the middle of another drag operation... + error "another drag operation in progress" + } + + variable _dodragdrop_drag_source $source + variable _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_proxy 0 + variable _dodragdrop_actions $actions + variable _dodragdrop_action_descriptions $actions + variable _dodragdrop_actions_len [llength $actions] + variable _dodragdrop_types $types + variable _dodragdrop_types_len [llength $types] + variable _dodragdrop_data $data + variable _dodragdrop_transfer_data {} + variable _dodragdrop_button $button + variable _dodragdrop_time 0 + variable _dodragdrop_default_action refuse_drop + variable _dodragdrop_waiting_status 0 + variable _dodragdrop_drop_target_accepts_drop 0 + variable _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_current_cursor $_dodragdrop_default_action + variable _dodragdrop_drop_occured 0 + variable _dodragdrop_selection_requestor 0 + + ## + ## If we have more than 3 types, the property XdndTypeList must be set on + ## the drag source widget... + ## + if {$_dodragdrop_types_len > 3} { + _announce_type_list $_dodragdrop_drag_source $_dodragdrop_types + } + + ## + ## Announce the actions & their descriptions on the XdndActionList & + ## XdndActionDescription properties... + ## + _announce_action_list $_dodragdrop_drag_source $_dodragdrop_actions \ + $_dodragdrop_action_descriptions + + ## + ## Arrange selection handlers for our drag source, and all the supported types + ## + registerSelectionHandler $source $types + + ## + ## Step 1: When a drag begins, the source takes ownership of XdndSelection. + ## + selection own -command ::tkdnd::xdnd::_selection_ownership_lost \ + -selection XdndSelection $source + set _dragging 1 + + ## Grab the mouse pointer... + _grab_pointer $source $_dodragdrop_default_action + + ## Register our generic event handler... + # The generic event callback will report events by modifying variable + # ::xdnd::_dodragdrop_event: a dict with event information will be set as + # the value of the variable... + _register_generic_event_handler + + ## Set a timeout for debugging purposes... + # after 60000 {set ::tkdnd::xdnd::_dragging 0} + + tkwait variable ::tkdnd::xdnd::_dragging + _SendXdndLeave + + set _dragging 0 + _ungrab_pointer $source + _unregister_generic_event_handler + catch {selection clear -selection XdndSelection} + unregisterSelectionHandler $source $types + return $_dodragdrop_drop_target_accepts_action +};# xdnd::_dodragdrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_process_drag_events +# ---------------------------------------------------------------------------- +proc xdnd::_process_drag_events {event} { + # The return value from proc is normally 0. A non-zero return value indicates + # that the event is not to be handled further; that is, proc has done all + # processing that is to be allowed for the event + variable _dragging + if {!$_dragging} {return 0} + # puts $event + + variable _dodragdrop_time + set time [dict get $event time] + set type [dict get $event type] + if {$time < $_dodragdrop_time && ![string equal $type SelectionRequest]} { + return 0 + } + set _dodragdrop_time $time + + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_default_action + switch $type { + MotionNotify { + set rootx [dict get $event x_root] + set rooty [dict get $event y_root] + set window [_find_drop_target_window $_dodragdrop_drag_source \ + $rootx $rooty] + if {[string length $window]} { + ## Examine the modifiers to suggest an action... + set _dodragdrop_default_action [_default_action $event] + ## Is it a Tk widget? + # set path [winfo containing $rootx $rooty] + # puts "Window under mouse: $window ($path)" + if {$_dodragdrop_drop_target != $window} { + ## Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + ## Is there a proxy? If not, _find_drop_target_proxy returns the + ## target window, so we always get a valid "proxy". + set proxy [_find_drop_target_proxy $_dodragdrop_drag_source $window] + ## Send XdndEnter to $window + _SendXdndEnter $window $proxy + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } else { + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } + } else { + ## No window under the mouse. Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + } + } + ButtonPress { + } + ButtonRelease { + variable _dodragdrop_button + set button [dict get $event button] + if {$button == $_dodragdrop_button} { + ## The button that initiated the drag was released. Trigger drop... + _SendXdndDrop + } + return 1 + } + KeyPress { + } + KeyRelease { + set keysym [dict get $event keysym] + switch $keysym { + Escape { + ## The user has pressed escape. Abort... + if {$_dragging} {set _dragging 0} + } + } + } + SelectionRequest { + variable _dodragdrop_selection_requestor + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + set _dodragdrop_selection_requestor [dict get $event requestor] + set _dodragdrop_selection_property [dict get $event property] + set _dodragdrop_selection_selection [dict get $event selection] + set _dodragdrop_selection_target [dict get $event target] + set _dodragdrop_selection_time $time + return 0 + } + default { + return 0 + } + } + return 0 +};# _process_drag_events + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndEnter {window proxy} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_types + variable _dodragdrop_waiting_status + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_target > 0} _SendXdndLeave + if {$_dodragdrop_drop_occured} return + set _dodragdrop_drop_target $window + set _dodragdrop_drop_target_proxy $proxy + set _dodragdrop_waiting_status 0 + if {$_dodragdrop_drop_target < 1} return + # puts "XdndEnter: $_dodragdrop_drop_target $_dodragdrop_drop_target_proxy" + _send_XdndEnter $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $_dodragdrop_types +};# xdnd::_SendXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndPosition {rootx rooty action} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_waiting_status + ## Arrange a new XdndPosition, to be send periodically... + variable _dodragdrop_xdnd_position_heartbeat + catch {after cancel $_dodragdrop_xdnd_position_heartbeat} + set _dodragdrop_xdnd_position_heartbeat [after 200 \ + [list ::tkdnd::xdnd::_SendXdndPosition $rootx $rooty $action]] + if {$_dodragdrop_waiting_status} {return} + # puts "XdndPosition: $_dodragdrop_drop_target $rootx $rooty $action" + _send_XdndPosition $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $rootx $rooty $action + set _dodragdrop_waiting_status 1 +};# xdnd::_SendXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndStatus +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndStatus {event} { + variable _dodragdrop_drop_target + variable _dodragdrop_waiting_status + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_waiting_status 0 + foreach key {target accept want_position action x y w h} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor + # puts "XdndStatus: $event" +};# xdnd::_HandleXdndStatus + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndFinished +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndFinished {event} { + variable _dodragdrop_xdnd_finished_event_after_id + catch {after cancel $_dodragdrop_xdnd_finished_event_after_id} + set _dodragdrop_xdnd_finished_event_after_id {} + variable _dodragdrop_drop_target + set _dodragdrop_drop_target 0 + variable _dragging + if {$_dragging} {set _dragging 0} + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + if {[dict size $event]} { + foreach key {target accept action} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + } else { + set _dodragdrop_drop_target_accepts_drop 0 + } + if {!$_dodragdrop_drop_target_accepts_drop} { + set _dodragdrop_drop_target_accepts_action refuse_drop + } + # puts "XdndFinished: $event" +};# xdnd::_HandleXdndFinished + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndLeave {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_target_proxy + # puts "XdndLeave: $_dodragdrop_drop_target" + _send_XdndLeave $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy + set _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_drop_target_accepts_drop 0 + set _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor +};# xdnd::_SendXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndDrop {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} { + ## The mouse has been released over a widget that does not accept drops. + _HandleXdndFinished {} + return + } + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} {return} + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + set _dodragdrop_drop_occured 1 + _update_cursor clock + + if {!$_dodragdrop_drop_target_accepts_drop} { + _SendXdndLeave + _HandleXdndFinished {} + return + } + # puts "XdndDrop: $_dodragdrop_drop_target" + variable _dodragdrop_drop_timestamp + set _dodragdrop_drop_timestamp [_send_XdndDrop \ + $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy] + set _dodragdrop_drop_target 0 + # puts "XdndDrop: $_dodragdrop_drop_target" + ## Arrange a timeout for receiving XdndFinished... + variable _dodragdrop_xdnd_finished_event_after_id + set _dodragdrop_xdnd_finished_event_after_id \ + [after 10000 [list ::tkdnd::xdnd::_HandleXdndFinished {}]] +};# xdnd::_SendXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_update_cursor +# ---------------------------------------------------------------------------- +proc xdnd::_update_cursor { {cursor {}}} { + # puts "_update_cursor $cursor" + variable _dodragdrop_current_cursor + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + if {![string length $cursor]} { + set cursor refuse_drop + if {$_dodragdrop_drop_target_accepts_drop} { + set cursor $_dodragdrop_drop_target_accepts_action + } + } + if {![string equal $cursor $_dodragdrop_current_cursor]} { + _set_pointer_cursor $_dodragdrop_drag_source $cursor + set _dodragdrop_current_cursor $cursor + } +};# xdnd::_update_cursor + +# ---------------------------------------------------------------------------- +# Command xdnd::_default_action +# ---------------------------------------------------------------------------- +proc xdnd::_default_action {event} { + variable _dodragdrop_actions + variable _dodragdrop_actions_len + if {$_dodragdrop_actions_len == 1} {return [lindex $_dodragdrop_actions 0]} + + set alt [dict get $event Alt] + set shift [dict get $event Shift] + set control [dict get $event Control] + + if {$shift && $control && [lsearch $_dodragdrop_actions link] != -1} { + return link + } elseif {$control && [lsearch $_dodragdrop_actions copy] != -1} { + return copy + } elseif {$shift && [lsearch $_dodragdrop_actions move] != -1} { + return move + } elseif {$alt && [lsearch $_dodragdrop_actions link] != -1} { + return link + } + return default +};# xdnd::_default_action + +# ---------------------------------------------------------------------------- +# Command xdnd::getFormatForType +# ---------------------------------------------------------------------------- +proc xdnd::getFormatForType {type} { + switch -glob [string tolower $type] { + text/plain\;charset=utf-8 - + text/html\;charset=utf-8 - + utf8_string {set format UTF8_STRING} + text/html - + text/plain - + string - + text - + compound_text {set format STRING} + text/uri-list* {set format UTF8_STRING} + application/x-color {set format $type} + default {set format $type} + } + return $format +};# xdnd::getFormatForType + +# ---------------------------------------------------------------------------- +# Command xdnd::registerSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::registerSelectionHandler {source types} { + foreach type $types { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source [list ::tkdnd::xdnd::_SendData $type] + } +};# xdnd::registerSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::unregisterSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::unregisterSelectionHandler {source types} { + foreach type $types { + catch { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source {} + } + } +};# xdnd::unregisterSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::_convert_to_unsigned +# ---------------------------------------------------------------------------- +proc xdnd::_convert_to_unsigned {data format} { + switch $format { + 8 { set mask 0xff } + 16 { set mask 0xffff } + 32 { set mask 0xffffff } + default {error "unsupported format $format"} + } + ## Convert signed integer into unsigned... + set d [list] + foreach num $data { + lappend d [expr { $num & $mask }] + } + return $d +};# xdnd::_convert_to_unsigned + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendData +# ---------------------------------------------------------------------------- +proc xdnd::_SendData {type offset bytes args} { + variable _dodragdrop_drag_source + variable _dodragdrop_types + variable _dodragdrop_data + variable _dodragdrop_transfer_data + + ## The variable _dodragdrop_data contains a list of data, one for each + ## type in the _dodragdrop_types variable. We have to search types, and find + ## the corresponding entry in the _dodragdrop_data list. + set index [lsearch $_dodragdrop_types $type] + if {$index < 0} { + error "unable to locate data suitable for type \"$type\"" + } + set typed_data [lindex $_dodragdrop_data $index] + set format 8 + if {$offset == 0} { + ## Prepare the data to be transferred... + switch -glob $type { + text/plain* - UTF8_STRING - STRING - TEXT - COMPOUND_TEXT { + binary scan [encoding convertto utf-8 $typed_data] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + text/uri-list* { + set files [list] + foreach file $typed_data { + switch -glob $file { + *://* {lappend files $file} + default {lappend files file://$file} + } + } + binary scan [encoding convertto utf-8 "[join $files \r\n]\r\n"] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + application/x-color { + set format 16 + ## Try to understand the provided data: we accept a standard Tk colour, + ## or a list of 3 values (red green blue) or a list of 4 values + ## (red green blue opacity). + switch [llength $typed_data] { + 1 { set color [winfo rgb $_dodragdrop_drag_source $typed_data] + lappend color 65535 } + 3 { set color $typed_data; lappend color 65535 } + 4 { set color $typed_data } + default {error "unknown color data: \"$typed_data\""} + } + ## Convert the 4 elements into 16 bit values... + set _dodragdrop_transfer_data [list] + foreach c $color { + lappend _dodragdrop_transfer_data [format 0x%04X $c] + } + } + default { + set format 32 + binary scan $typed_data c* _dodragdrop_transfer_data + } + } + } + + ## + ## Data has been split into bytes. Count the bytes requested, and return them + ## + set data [lrange $_dodragdrop_transfer_data $offset [expr {$offset+$bytes-1}]] + switch $format { + 8 { + set data [encoding convertfrom utf-8 [binary format c* $data]] + } + 16 { + variable _dodragdrop_selection_requestor + if {$_dodragdrop_selection_requestor} { + ## Tk selection cannot process this format (only 8 & 32 supported). + ## Call our XChangeProperty... + set numItems [llength $data] + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + XChangeProperty $_dodragdrop_drag_source \ + $_dodragdrop_selection_requestor \ + $_dodragdrop_selection_property \ + $_dodragdrop_selection_target \ + $format \ + $_dodragdrop_selection_time \ + $data $numItems + return -code break + } + } + 32 { + } + default { + error "unsupported format $format" + } + } + # puts "SendData: $type $offset $bytes $args ($typed_data)" + # puts " $data" + return $data +};# xdnd::_SendData diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_utils.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_utils.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ee961ddb1ca29b383496111eadc2ccdce7776b08 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_utils.tcl @@ -0,0 +1,252 @@ +# +# tkdnd_utils.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require tkdnd +namespace eval ::tkdnd { + namespace eval utils { + };# namespace ::tkdnd::utils + namespace eval text { + variable _drag_tag tkdnd::drag::selection::tag + variable _state {} + variable _drag_source_widget {} + variable _drop_target_widget {} + variable _now_dragging 0 + };# namespace ::tkdnd::text +};# namespace ::tkdnd + +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag clear 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag motion 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_TextAutoScan %W %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag reset 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag clear 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag motion 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag reset 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag clear 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag motion 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag reset 3 %W %s %X %Y %x %y} + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drag_source { mode path { types DND_Text } { event 1 } { tagprefix TkDND_Drag_Text } { tag sel } } { + switch -exact -- $mode { + register { + $path tag bind $tag \ + "tkdnd::text::_begin_drag press ${event} %W %s %X %Y %x %y" + ## Set a binding to the widget, to put selection as data... + bind $path <> "::tkdnd::text::DragInitCmd $path {%t} $tag" + ## Set a binding to the widget, to remove selection if action is move... + bind $path <> "::tkdnd::text::DragEndCmd $path %A $tag" + } + unregister { + $path tag bind $tag {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drag_source $mode $path $types $event $tagprefix +};# ::tkdnd::text::drag_source + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drop_target { mode path { types DND_Text } } { + switch -exact -- $mode { + register { + bind $path <> "::tkdnd::text::DropPosition $path %X %Y %A %a %m" + bind $path <> "::tkdnd::text::Drop $path %D %X %Y %A %a %m" + } + unregister { + bind $path <> {} + bind $path <> {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drop_target $mode $path $types +};# ::tkdnd::text::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragInitCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragInitCmd { path { types DND_Text } { tag sel } { actions { copy move } } } { + ## Save the selection indices... + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget $path + set _drop_target_widget {} + _save_selection $path $tag + list $actions $types [$path get $tag.first $tag.last] +};# ::tkdnd::text::DragInitCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragEndCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragEndCmd { path action { tag sel } } { + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget {} + set _drop_target_widget {} + _restore_selection $path $tag + switch -exact -- $action { + move { + ## Delete the original selected text... + variable _selection_first + variable _selection_last + $path delete $_selection_first $_selection_last + } + } +};# ::tkdnd::text::DragEndCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DropPosition +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DropPosition { path X Y action actions keys} { + variable _drag_source_widget + variable _drop_target_widget + set _drop_target_widget $path + ## This check is primitive, a more accurate one is needed! + if {$path eq $_drag_source_widget} { + ## This is a drag within the same widget! Set action to move... + if {"move" in $actions} {set action move} + } + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y; update + return $action +};# ::tkdnd::text::DropPosition + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::Drop +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::Drop { path data X Y action actions keys } { + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y + $path insert [$path index insert] $data + return $action +};# ::tkdnd::text::Drop + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_save_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_save_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + variable _selection_tag $tag + set _selection_first [$path index $tag.first] + set _selection_last [$path index $tag.last] + $path tag add $_drag_tag $_selection_first $_selection_last + $path tag configure $_drag_tag \ + -background [$path tag cget $tag -background] \ + -foreground [$path tag cget $tag -foreground] +};# tkdnd::text::_save_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_restore_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_restore_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + $path tag delete $_drag_tag + $path tag remove $tag 0.0 end + #$path tag add $tag $_selection_first $_selection_last +};# tkdnd::text::_restore_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_begin_drag { event button source state X Y x y } { + variable _drop_target_widget + variable _state + # puts "::tkdnd::text::_begin_drag $event $button $source $state $X $Y $x $y" + + switch -exact -- $event { + clear { + switch -exact -- $_state { + press { + ## Do not execute other bindings, as they will erase selection... + return -code break + } + } + set _state clear + } + motion { + variable _now_dragging + if {$_now_dragging} {return -code break} + if { [string equal $_state "press"] } { + variable _x0; variable _y0 + if { abs($_x0-$X) > ${::tkdnd::_dx} || abs($_y0-$Y) > ${::tkdnd::_dy} } { + set _state "done" + set _drop_target_widget {} + set _now_dragging 1 + set code [catch { + ::tkdnd::_init_drag $button $source $state $X $Y $x $y + } info options] + set _drop_target_widget {} + set _now_dragging 0 + if {$code != 0} { + ## Something strange occurred... + return -options $options $info + } + } + return -code break + } + set _state clear + } + press { + variable _x0; variable _y0 + set _x0 $X + set _y0 $Y + set _state "press" + } + reset { + set _state {} + } + } + if {$source eq $_drop_target_widget} {return -code break} + return -code continue +};# tkdnd::text::_begin_drag + +proc tkdnd::text::_TextAutoScan {w x y} { + variable _now_dragging + if {$_now_dragging} {return -code break} + return -code continue +};# tkdnd::text::_TextAutoScan diff --git a/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_windows.tcl b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_windows.tcl new file mode 100644 index 0000000000000000000000000000000000000000..a1d01f3a2c438eaf3f676437d4d4ba89b3ba64f0 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx64/tkdnd_windows.tcl @@ -0,0 +1,167 @@ +# +# tkdnd_windows.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval olednd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + CF_UNICODETEXT DND_Text \ + CF_TEXT DND_Text \ + CF_HDROP DND_Files \ + UniformResourceLocator DND_URL \ + CF_HTML DND_HTML \ + {HTML Format} DND_HTML \ + CF_RTF DND_RTF \ + CF_RTFTEXT DND_RTF \ + {Rich Text Format} DND_RTF \ + ] + # FileGroupDescriptorW DND_Files \ + # FileGroupDescriptor DND_Files \ + + ## Mapping from TkDND types to platform types... + ::tkdnd::generic::initialise_tkdnd_to_platform_types [list \ + DND_Text {CF_UNICODETEXT CF_TEXT} \ + DND_Files {CF_HDROP} \ + DND_URL {UniformResourceLocator UniformResourceLocatorW} \ + DND_HTML {CF_HTML {HTML Format}} \ + DND_RTF {CF_RTF CF_RTFTEXT {Rich Text Format}} \ + ] + };# initialise + +};# namespace olednd + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragEnter +# ---------------------------------------------------------------------------- +proc olednd::HandleDragEnter { drop_target typelist actionlist pressedkeys + rootX rootY codelist { data {} } } { + ::tkdnd::generic::SetDroppedData $data + focus $drop_target + ::tkdnd::generic::HandleEnter $drop_target 0 $typelist \ + $codelist $actionlist $pressedkeys + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragEnter + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragOver +# ---------------------------------------------------------------------------- +proc olednd::HandleDragOver { drop_target pressedkeys rootX rootY } { + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragOver + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragLeave +# ---------------------------------------------------------------------------- +proc olednd::HandleDragLeave { drop_target } { + ::tkdnd::generic::HandleLeave + if {$::tkdnd::_auto_update} {update idletasks} +};# olednd::HandleDragLeave + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDrop +# ---------------------------------------------------------------------------- +proc olednd::HandleDrop { drop_target pressedkeys rootX rootY type data } { + ::tkdnd::generic::SetDroppedData [normalise_data $type $data] + set action [::tkdnd::generic::HandleDrop $drop_target {} \ + $pressedkeys $rootX $rootY 0] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command olednd::GetDataType +# ---------------------------------------------------------------------------- +proc olednd::GetDataType { drop_target typelist } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + lindex $common_drag_source_types 0 +};# olednd::GetDataType + +# ---------------------------------------------------------------------------- +# Command olednd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc olednd::GetDragSourceCommonTypes { drop_target } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# olednd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_types +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # olednd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_type +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # olednd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_independent_type +# ---------------------------------------------------------------------------- +proc olednd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # olednd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command olednd::normalise_data +# ---------------------------------------------------------------------------- +proc olednd::normalise_data { type data } { + switch [lindex [::tkdnd::generic::platform_independent_type $type] 0] { + DND_Text {return $data} + DND_Files {return $data} + DND_HTML {return [encoding convertfrom utf-8 $data]} + default {return $data} + } +}; # olednd::normalise_data diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/libtkdnd2.9.3.dylib b/gui_data/tkinterdnd2/tkdnd/osx_arm/libtkdnd2.9.3.dylib new file mode 100644 index 0000000000000000000000000000000000000000..9efdec82229fc40f474900a00c93a862f7038262 Binary files /dev/null and b/gui_data/tkinterdnd2/tkdnd/osx_arm/libtkdnd2.9.3.dylib differ diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/pkgIndex.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/pkgIndex.tcl new file mode 100644 index 0000000000000000000000000000000000000000..35b4d1c1a4f61c538ee65f39373093008e334bd5 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/pkgIndex.tcl @@ -0,0 +1,62 @@ +# +# Tcl package index file +# + +namespace eval ::tkdnd { + ## Check if a debug level must be set... + if {[info exists ::TKDND_DEBUG_LEVEL]} { + variable _debug_level $::TKDND_DEBUG_LEVEL + } elseif {[info exists ::env(TKDND_DEBUG_LEVEL)]} { + variable _debug_level $::env(TKDND_DEBUG_LEVEL) + } else { + variable _debug_level 0 + } + + # ---------------------------------------------------------------------------- + # Command tkdnd::debug_enabled: returns the requested debug level (0 = no debug). + # ---------------------------------------------------------------------------- + proc debug_enabled { {level {}} } { + variable _debug_level + if {$level != {}} { + if {[string is integer -strict $level]} { + set _debug_level $level + } elseif {[string is true $level]} { + set _debug_level 1 + } + } + return $_debug_level + };# debug_enabled + + # ---------------------------------------------------------------------------- + # Command tkdnd::source: source a Tcl fileInitialise the TkDND package. + # ---------------------------------------------------------------------------- + proc source { filename { encoding utf-8 } } { + variable _package_dir + # If in debug mode, enable debug statements... + set dbg_lvl [debug_enabled] + if {$dbg_lvl} { + puts "tkdnd::source (debug level $dbg_lvl) $filename" + set fd [open $filename r] + fconfigure $fd -encoding $encoding + set script [read $fd] + close $fd + set map {} + for {set lvl 0} {$lvl <= $dbg_lvl} {incr lvl} { + lappend map "#DBG$lvl " {} + } + lappend map {#DBG } {} + set script [string map $map $script] + return [eval $script] + } + ::source -encoding $encoding $filename + };# source + +}; # namespace ::tkdnd + +package ifneeded tkdnd 2.9.3 \ + "tkdnd::source \{$dir/tkdnd.tcl\} ; \ + tkdnd::initialise \{$dir\} libtkdnd2.9.3.dylib tkdnd" + +package ifneeded tkdnd::utils 2.9.3 \ + "tkdnd::source \{$dir/tkdnd_utils.tcl\} ; \ + package provide tkdnd::utils 2.9.3" diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd.tcl new file mode 100644 index 0000000000000000000000000000000000000000..05f62bf8ae8a652a248fddae31a63704f76b912c --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd.tcl @@ -0,0 +1,539 @@ +# +# tkdnd.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require Tk + +namespace eval ::tkdnd { + variable _package_dir {} + variable _topw ".drag" + variable _tabops + variable _state + variable _x0 + variable _y0 + variable _platform_namespace + variable _drop_file_temp_dir + variable _auto_update 1 + variable _dx 3 ;# The difference in pixels before a drag is initiated. + variable _dy 3 ;# The difference in pixels before a drag is initiated. + + variable _windowingsystem + + if {[info exists ::TKDND_DEBUG_LEVEL]} { + variable _debug_level $::TKDND_DEBUG_LEVEL + } elseif {[info exists ::env(TKDND_DEBUG_LEVEL)]} { + variable _debug_level $::env(TKDND_DEBUG_LEVEL) + } else { + variable _debug_level 0 + } + + bind TkDND_Drag1 {tkdnd::_begin_drag press 1 %W %s %X %Y %x %y} + bind TkDND_Drag1 {tkdnd::_begin_drag motion 1 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag press 2 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag motion 2 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag press 3 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag motion 3 %W %s %X %Y %x %y} + + # ---------------------------------------------------------------------------- + # Command tkdnd::debug_enabled: returns the requested debug level (0 = no debug). + # ---------------------------------------------------------------------------- + proc debug_enabled { {level {}} } { + variable _debug_level + if {$level != {}} { + if {[string is integer -strict $level]} { + set _debug_level $level + } elseif {[string is true $level]} { + set _debug_level 1 + } + } + return $_debug_level + };# debug_enabled + + # ---------------------------------------------------------------------------- + # Command tkdnd::source: source a Tcl fileInitialise the TkDND package. + # ---------------------------------------------------------------------------- + proc source { filename { encoding utf-8 } } { + variable _package_dir + # If in debug mode, enable debug statements... + set dbg_lvl [debug_enabled] + if {$dbg_lvl} { + puts "tkdnd::source (debug level $dbg_lvl) $filename" + set fd [open $filename r] + fconfigure $fd -encoding $encoding + set script [read $fd] + close $fd + set map {} + for {set lvl 0} {$lvl <= $dbg_lvl} {incr lvl} { + lappend map "\#\D\B\G$lvl " {} ;# Do not remove these \\ + } + lappend map "\#\D\B\G\ " {} ;# Do not remove these \\ + set script [string map $map $script] + return [eval $script] + } + ::source -encoding $encoding $filename + };# source + + # ---------------------------------------------------------------------------- + # Command tkdnd::initialise: Initialise the TkDND package. + # ---------------------------------------------------------------------------- + proc initialise { dir PKG_LIB_FILE PACKAGE_NAME} { + variable _package_dir + variable _platform_namespace + variable _drop_file_temp_dir + variable _windowingsystem + global env + + set _package_dir $dir + + switch [tk windowingsystem] { + x11 { + set _windowingsystem x11 + } + win32 - + windows { + set _windowingsystem windows + } + aqua { + set _windowingsystem aqua + } + default { + error "unknown Tk windowing system" + } + } + + ## Get User's home directory: We try to locate the proper path from a set of + ## environmental variables... + foreach var {HOME HOMEPATH USERPROFILE ALLUSERSPROFILE APPDATA} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)]} { + set UserHomeDir $env($var) + break + } + } + } + + ## Should use [tk windowingsystem] instead of tcl platform array: + ## OS X returns "unix," but that's not useful because it has its own + ## windowing system, aqua + ## Under windows we have to also combine HOMEDRIVE & HOMEPATH... + if {![info exists UserHomeDir] && + [string equal $_windowingsystem windows] && + [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { + if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { + set UserHomeDir $env(HOMEDRIVE)$env(HOMEPATH) + } + } + ## Have we located the needed path? + if {![info exists UserHomeDir]} { + set UserHomeDir [pwd] + } + set UserHomeDir [file normalize $UserHomeDir] + + ## Try to locate a temporary directory... + foreach var {TKDND_TEMP_DIR TEMP TMP} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)] && [file writable $env($var)]} { + set _drop_file_temp_dir $env($var) + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + foreach _dir [list "$UserHomeDir/Local Settings/Temp" \ + "$UserHomeDir/AppData/Local/Temp" \ + /tmp \ + C:/WINDOWS/Temp C:/Temp C:/tmp \ + D:/WINDOWS/Temp D:/Temp D:/tmp] { + if {[file isdirectory $_dir] && [file writable $_dir]} { + set _drop_file_temp_dir $_dir + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + set _drop_file_temp_dir $UserHomeDir + } + set _drop_file_temp_dir [file native $_drop_file_temp_dir] + + source $dir/tkdnd_generic.tcl + switch $_windowingsystem { + x11 { + source $dir/tkdnd_unix.tcl + set _platform_namespace xdnd + } + win32 - + windows { + source $dir/tkdnd_windows.tcl + set _platform_namespace olednd + } + aqua { + source $dir/tkdnd_macosx.tcl + set _platform_namespace macdnd + } + default { + error "unknown Tk windowing system" + } + } + load $dir/$PKG_LIB_FILE $PACKAGE_NAME + source $dir/tkdnd_compat.tcl + ${_platform_namespace}::initialise + };# initialise + + proc GetDropFileTempDirectory { } { + variable _drop_file_temp_dir + return $_drop_file_temp_dir + } + proc SetDropFileTempDirectory { dir } { + variable _drop_file_temp_dir + set _drop_file_temp_dir $dir + } + + proc debug {msg} { + puts $msg + };# debug + +};# namespace ::tkdnd + +# ---------------------------------------------------------------------------- +# Command tkdnd::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::drag_source { mode path { types {} } { event 1 } + { tagprefix TkDND_Drag } } { + #DBG debug "::tkdnd::drag_source $mode $path $types $event $tagprefix" + foreach single_event $event { + set tags [bindtags $path] + set idx [lsearch $tags ${tagprefix}$single_event] + switch -- $mode { + register { + if { $idx != -1 } { + ## No need to do anything! + # bindtags $path [lreplace $tags $idx $idx ${tagprefix}$single_event] + } else { + bindtags $path [linsert $tags 1 ${tagprefix}$single_event] + } + _drag_source_update_types $path $types + } + unregister { + if { $idx != -1 } { + bindtags $path [lreplace $tags $idx $idx] + } + } + } + } +};# tkdnd::drag_source + +proc ::tkdnd::_drag_source_update_types { path types } { + set types [platform_specific_types $types] + set old_types [bind $path <>] + foreach type $types { + if {[lsearch $old_types $type] < 0} {lappend old_types $type} + } + bind $path <> $old_types +};# ::tkdnd::_drag_source_update_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::drop_target { mode path { types {} } } { + variable _windowingsystem + set types [platform_specific_types $types] + switch -- $mode { + register { + switch $_windowingsystem { + x11 { + _register_types $path [winfo toplevel $path] $types + } + win32 - + windows { + _RegisterDragDrop $path + bind $path {+ tkdnd::_RevokeDragDrop %W} + } + aqua { + macdnd::registerdragwidget [winfo toplevel $path] $types + } + default { + error "unknown Tk windowing system" + } + } + set old_types [bind $path <>] + set new_types {} + foreach type $types { + if {[lsearch -exact $old_types $type] < 0} {lappend new_types $type} + } + if {[llength $new_types]} { + bind $path <> [concat $old_types $new_types] + } + } + unregister { + switch $_windowingsystem { + x11 { + } + win32 - + windows { + _RevokeDragDrop $path + } + aqua { + error todo + } + default { + error "unknown Tk windowing system" + } + } + bind $path <> {} + } + } +};# tkdnd::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_begin_drag { event button source state X Y x y } { + variable _x0 + variable _y0 + variable _state + + switch -- $event { + press { + set _x0 $X + set _y0 $Y + set _state "press" + } + motion { + if { ![info exists _state] } { + # This is just extra protection. There seem to be + # rare cases where the motion comes before the press. + return + } + if { [string equal $_state "press"] } { + variable _dx + variable _dy + if { abs($_x0-$X) > ${_dx} || abs($_y0-$Y) > ${_dy} } { + set _state "done" + _init_drag $button $source $state $X $Y $x $y + } + } + } + } +};# tkdnd::_begin_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_init_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_init_drag { button source state rootX rootY X Y } { + #DBG debug "::tkdnd::_init_drag $button $source $state $rootX $rootY $X $Y" + # Call the <> binding. + set cmd [bind $source <>] + #DBG debug "CMD: $cmd" + if {[string length $cmd]} { + set cmd [string map [list %W [list $source] \ + %X $rootX %Y $rootY %x $X %y $Y \ + %S $state %e <> %A \{\} %% % \ + %b \{$button\} \ + %t \{[bind $source <>]\}] $cmd] + set code [catch {uplevel \#0 $cmd} info options] + #DBG debug "CODE: $code ---- $info" + switch -exact -- $code { + 0 {} + 3 - 4 { + # FRINK: nocheck + return + } + default { + return -options $options $info + } + } + + set len [llength $info] + if {$len == 3} { + foreach { actions types _data } $info { break } + set types [platform_specific_types $types] + set data [list] + foreach type $types { + lappend data $_data + } + unset _data + } elseif {$len == 2} { + foreach { actions _data } $info { break } + set data [list]; set types [list] + foreach {t d} $_data { + foreach t [platform_specific_types $t] { + lappend types $t; lappend data $d + } + } + unset _data t d + } else { + foreach { actions } $info { break } + if {$len == 1 && [string equal [lindex $actions 0] "refuse_drop"]} { + return + } + error "not enough items in the result of the <>\ + event binding. Either 2 or 3 items are expected. The command + executed was: \"$cmd\"\nResult was: \"$info\"" + } + set action refuse_drop + + ## Custom Cursors... + # Call the <> binding. + set cursor_map [bind $source <>] + + variable _windowingsystem + #DBG debug "Source: \"$source\"" + #DBG debug "Types: \"[join $types {", "}]\"" + #DBG debug "Actions: \"[join $actions {", "}]\"" + #DBG debug "Button: \"$button\"" + #DBG debug "Data: \"[string range $data 0 100]\"" + #DBG debug "CursorMap: \"[string range $cursor_map 0 100]\"" + switch $_windowingsystem { + x11 { + set action [xdnd::_dodragdrop $source $actions $types $data $button $cursor_map] + } + win32 - + windows { + set action [_DoDragDrop $source $actions $types $data $button] + } + aqua { + set action [macdnd::dodragdrop $source $actions $types $data $button] + } + default { + error "unknown Tk windowing system" + } + } + ## Call _end_drag to notify the widget of the result of the drag + ## operation... + _end_drag $button $source {} $action {} $data {} $state $rootX $rootY $X $Y + } +};# tkdnd::_init_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_end_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_end_drag { button source target action type data result + state rootX rootY X Y } { + set rootX 0 + set rootY 0 + # Call the <> binding. + set cmd [bind $source <>] + if {[string length $cmd]} { + set cmd [string map [list %W [list $source] \ + %X $rootX %Y $rootY %x $X %y $Y %% % \ + %b \{$button\} \ + %S $state %e <> %A \{$action\}] $cmd] + set info [uplevel \#0 $cmd] + # if { $info != "" } { + # variable _windowingsystem + # foreach { actions types data } $info { break } + # set types [platform_specific_types $types] + # switch $_windowingsystem { + # x11 { + # error "dragging from Tk widgets not yet supported" + # } + # win32 - + # windows { + # set action [_DoDragDrop $source $actions $types $data $button] + # } + # aqua { + # macdnd::dodragdrop $source $actions $types $data + # } + # default { + # error "unknown Tk windowing system" + # } + # } + # ## Call _end_drag to notify the widget of the result of the drag + # ## operation... + # _end_drag $button $source {} $action {} $data {} $state $rootX $rootY + # } + } +};# tkdnd::_end_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_types $types +}; # tkdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_type $type +}; # tkdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_type $type +}; # tkdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::bytes_to_string +# ---------------------------------------------------------------------------- +proc ::tkdnd::bytes_to_string { bytes } { + set string {} + foreach byte $bytes { + append string [binary format c $byte] + } + return $string +};# tkdnd::bytes_to_string + +# ---------------------------------------------------------------------------- +# Command tkdnd::urn_unquote +# ---------------------------------------------------------------------------- +proc ::tkdnd::urn_unquote {url} { + set result "" + set start 0 + while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { + foreach {first last} $match break + append result [string range $url $start [expr {$first - 1}]] + append result [format %c 0x[string range $url [incr first] $last]] + set start [incr last] + } + append result [string range $url $start end] + return [encoding convertfrom utf-8 $result] +};# tkdnd::urn_unquote diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_compat.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_compat.tcl new file mode 100644 index 0000000000000000000000000000000000000000..efc96f7bb2fe74a9bafd1e79681c275c8ea0f8fc --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_compat.tcl @@ -0,0 +1,160 @@ +# +# tkdnd_compat.tcl -- +# +# This file implements some utility procedures, to support older versions +# of the TkDND package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval compat { + +};# namespace compat + +# ---------------------------------------------------------------------------- +# Command ::dnd +# ---------------------------------------------------------------------------- +proc ::dnd {method window args} { + switch $method { + bindtarget { + switch [llength $args] { + 0 {return [tkdnd::compat::bindtarget0 $window]} + 1 {return [tkdnd::compat::bindtarget1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindtarget2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindtarget3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + 4 {return [tkdnd::compat::bindtarget4 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2] [lindex $args 3]]} + } + } + cleartarget { + return [tkdnd::compat::cleartarget $window] + } + bindsource { + switch [llength $args] { + 0 {return [tkdnd::compat::bindsource0 $window]} + 1 {return [tkdnd::compat::bindsource1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindsource2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindsource3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + } + } + clearsource { + return [tkdnd::compat::clearsource $window] + } + drag { + return [tkdnd::_init_drag 1 $window "press" 0 0 0 0] + } + } + error "invalid number of arguments!" +};# ::dnd + +# ---------------------------------------------------------------------------- +# Command compat::bindtarget +# ---------------------------------------------------------------------------- +proc compat::bindtarget0 {window} { + return [bind $window <>] +};# compat::bindtarget0 + +proc compat::bindtarget1 {window type} { + return [bindtarget2 $window $type ] +};# compat::bindtarget1 + +proc compat::bindtarget2 {window type event} { + switch $event { + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + } +};# compat::bindtarget2 + +proc compat::bindtarget3 {window type event script} { + set type [normalise_type $type] + ::tkdnd::drop_target register $window [list $type] + switch $event { + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + } +};# compat::bindtarget3 + +proc compat::bindtarget4 {window type event script priority} { + return [bindtarget3 $window $type $event $script] +};# compat::bindtarget4 + +proc compat::normalise_type { type } { + switch $type { + text/plain - + {text/plain;charset=UTF-8} - + Text {return DND_Text} + text/uri-list - + Files {return DND_Files} + default {return $type} + } +};# compat::normalise_type + +# ---------------------------------------------------------------------------- +# Command compat::bindsource +# ---------------------------------------------------------------------------- +proc compat::bindsource0 {window} { + return [bind $window <>] +};# compat::bindsource0 + +proc compat::bindsource1 {window type} { + return [bindsource2 $window $type ] +};# compat::bindsource1 + +proc compat::bindsource2 {window type script} { + set type [normalise_type $type] + ::tkdnd::drag_source register $window $type + bind $window <> "list {copy} {%t} \[$script\]" +};# compat::bindsource2 + +proc compat::bindsource3 {window type script priority} { + return [bindsource2 $window $type $script] +};# compat::bindsource3 + +# ---------------------------------------------------------------------------- +# Command compat::cleartarget +# ---------------------------------------------------------------------------- +proc compat::cleartarget {window} { +};# compat::cleartarget + +# ---------------------------------------------------------------------------- +# Command compat::clearsource +# ---------------------------------------------------------------------------- +proc compat::clearsource {window} { +};# compat::clearsource diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_generic.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_generic.tcl new file mode 100644 index 0000000000000000000000000000000000000000..2ffcb98c21ba1d6a2a37c6798daaf909b5155d93 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_generic.tcl @@ -0,0 +1,587 @@ +# +# tkdnd_generic.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval generic { + variable _types {} + variable _typelist {} + variable _codelist {} + variable _actionlist {} + variable _pressedkeys {} + variable _pressedmods {} + variable _action {} + variable _common_drag_source_types {} + variable _common_drop_target_types {} + variable _drag_source {} + variable _drop_target {} + + variable _last_mouse_root_x 0 + variable _last_mouse_root_y 0 + + variable _tkdnd2platform + variable _platform2tkdnd + + variable _integer_test entier + if {[catch {string is entier 1234}]} { + set _integer_test integer + } + + proc debug { msg } { + tkdnd::debug $msg + };# debug + + proc initialise { } { + };# initialise + + proc initialise_platform_to_tkdnd_types { types } { + variable _platform2tkdnd + variable _tkdnd2platform + # set _platform2tkdnd [dict create {*}$types] ;# {*} not available in 8.4 + set _platform2tkdnd [dict create] + foreach {p t} $types { + dict set _platform2tkdnd $p $t + } + set _tkdnd2platform [dict create] + foreach type [dict keys $_platform2tkdnd] { + dict lappend _tkdnd2platform [dict get $_platform2tkdnd $type] $type + } + };# initialise_platform_to_tkdnd_types + + proc initialise_tkdnd_to_platform_types { types } { + variable _tkdnd2platform + # set _tkdnd2platform [dict create {*}$types] ;# {*} not available in 8.4 + set _tkdnd2platform [dict create] + foreach {t p} $types { + dict set _tkdnd2platform $t $p + } + };# initialise_tkdnd_to_platform_types + +};# namespace generic + +# ---------------------------------------------------------------------------- +# Command generic::SetPressedKeys +# ---------------------------------------------------------------------------- +proc generic::SetPressedKeys { pressedkeys } { + variable _pressedkeys + variable _pressedmods + variable _integer_test + set keys {} + set mods {} + foreach {b} $pressedkeys { + if {[string is $_integer_test -strict $b]} { + lappend keys $b + } else { + lappend mods $b + } + } + set _pressedkeys $keys + set _pressedmods $mods +};# generic::SetPressedKeys + +# ---------------------------------------------------------------------------- +# Command generic::HandleEnter +# ---------------------------------------------------------------------------- +proc generic::HandleEnter { drop_target drag_source typelist codelist + actionlist pressedkeys } { + variable _typelist; set _typelist $typelist + variable _action; set _action refuse_drop + variable _common_drag_source_types; set _common_drag_source_types {} + variable _common_drop_target_types; set _common_drop_target_types {} + variable _actionlist + variable _drag_source; set _drag_source $drag_source + variable _drop_target; set _drop_target {} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist + + variable _last_mouse_root_x; set _last_mouse_root_x 0 + variable _last_mouse_root_y; set _last_mouse_root_y 0 + SetPressedKeys $pressedkeys + #DBG debug "\n===============================================================" + #DBG debug "generic::HandleEnter: drop_target=$drop_target,\ + #DBG drag_source=$drag_source,\ + #DBG typelist=$typelist" + #DBG debug "generic::HandleEnter: ACTION: default" + return default +};# generic::HandleEnter + +# ---------------------------------------------------------------------------- +# Command generic::HandlePosition +# ---------------------------------------------------------------------------- +proc generic::HandlePosition { drop_target drag_source pressedkeys + rootX rootY { action {} } { time 0 } } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _pressedmods + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + #DBG debug "generic::HandlePosition: drop_target=$drop_target,\ + #DBG _drop_target=$_drop_target, rootX=$rootX, rootY=$rootY" + + if {![info exists _drag_source] || ![string length $_drag_source]} { + #DBG debug "generic::HandlePosition: no or empty _drag_source:\ + #DBG return refuse_drop" + return refuse_drop + } + + if {$drag_source ne "" && $drag_source ne $_drag_source} { + #DBG debug "generic position event from unexpected source: $_drag_source\ + #DBG != $drag_source" + return refuse_drop + } + + SetPressedKeys $pressedkeys + + ## Does the new drop target support any of our new types? + # foreach {common_drag_source_types common_drop_target_types} \ + # [GetWindowCommonTypes $drop_target $_typelist] {break} + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [FindWindowWithCommonTypes $drop_target $_typelist] {break} + set data [GetDroppedData $time] + + #DBG debug "\t($_drop_target) -> ($drop_target)" + if {$drop_target != $_drop_target} { + if {[string length $_drop_target]} { + ## Call the <> event. + #DBG debug "\t<> on $_drop_target" + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$rootX - [winfo rootx $_drop_target]}]} + catch {set widgetY [expr {$rootY - [winfo rooty $_drop_target]}]} + set cmd [string map [list %W [list $_drop_target] \ + %X $rootX %Y $rootY %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + uplevel \#0 $cmd + } + } + set _drop_target $drop_target + set _action refuse_drop + + if {[llength $common_drag_source_types]} { + switch -exact -- $action { + default - {} { set _action [lindex $_actionlist 0] } + default { set _action $action } + } + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + ## Drop target supports at least one type. Send a <>. + #DBG debug "<> -> $drop_target" + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$rootX - [winfo rootx $drop_target]}]} + catch {set widgetY [expr {$rootY - [winfo rooty $drop_target]}]} + focus $drop_target + set cmd [string map [list %W [list $drop_target] \ + %X $rootX %Y $rootY %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + } + } + } + + set _drop_target {} + if {[llength $common_drag_source_types]} { + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <>. + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + switch -exact -- $action { + default - {} { set _action [lindex $_actionlist 0] } + default { set _action $action } + } + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$rootX - [winfo rootx $drop_target]}]} + catch {set widgetY [expr {$rootY - [winfo rooty $drop_target]}]} + set cmd [string map [list %W [list $drop_target] \ + %X $rootX %Y $rootY %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + # Return values: copy, move, link, ask, private, refuse_drop, default + #DBG debug "generic::HandlePosition: ACTION: $_action" + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandlePosition + +# ---------------------------------------------------------------------------- +# Command generic::HandleLeave +# ---------------------------------------------------------------------------- +proc generic::HandleLeave { } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _pressedmods + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + if {![info exists _drop_target]} {set _drop_target {}} + #DBG debug "generic::HandleLeave: _drop_target=$_drop_target" + if {[info exists _drop_target] && [string length $_drop_target]} { + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$_last_mouse_root_x - [winfo rootx $_drop_target]}]} + catch {set widgetY [expr {$_last_mouse_root_y - [winfo rooty $_drop_target]}]} + set cmd [string map [list %W [list $_drop_target] \ + %X $_last_mouse_root_x %Y $_last_mouse_root_y %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + foreach var {_types _typelist _actionlist _pressedkeys _pressedmods _action + _common_drag_source_types _common_drop_target_types + _drag_source _drop_target} { + set $var {} + } +};# generic::HandleLeave + +# ---------------------------------------------------------------------------- +# Command generic::HandleDrop +# ---------------------------------------------------------------------------- +proc generic::HandleDrop {drop_target drag_source pressedkeys rootX rootY time } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _pressedmods + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + SetPressedKeys $pressedkeys + + #DBG debug "generic::HandleDrop: $time" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + return refuse_drop + } + if {![info exists _drop_target] && ![string length $_drop_target]} { + return refuse_drop + } + if {![llength $_common_drag_source_types]} {return refuse_drop} + ## Get the dropped data. + set data [GetDroppedData $time] + ## Try to select the most specific <> event. + foreach type [concat $_common_drag_source_types $_common_drop_target_types] { + set type [platform_independent_type $type] + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$rootX - [winfo rootx $_drop_target]}]} + catch {set widgetY [expr {$rootY - [winfo rooty $_drop_target]}]} + set cmd [string map [list %W [list $_drop_target] \ + %X $rootX %Y $rootY %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action + } + } + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set widgetX 0; set widgetY 0 + catch {set widgetX [expr {$rootX - [winfo rootx $_drop_target]}]} + catch {set widgetY [expr {$rootY - [winfo rooty $_drop_target]}]} + set cmd [string map [list %W [list $_drop_target] \ + %X $rootX %Y $rootY %x $widgetX %y $widgetY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedmods\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandleDrop + +# ---------------------------------------------------------------------------- +# Command generic::GetWindowCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetWindowCommonTypes { win typelist } { + set types [bind $win <>] + #DBG debug ">> Accepted types: $win $_types" + set common_drag_source_types {} + set common_drop_target_types {} + if {[llength $types]} { + ## Examine the drop target types, to find at least one match with the drag + ## source types... + set supported_types [supported_types $typelist] + foreach type $types { + foreach matched [lsearch -glob -all -inline $supported_types $type] { + ## Drop target supports this type. + lappend common_drag_source_types $matched + lappend common_drop_target_types $type + } + } + } + list $common_drag_source_types $common_drop_target_types +};# generic::GetWindowCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::FindWindowWithCommonTypes +# ---------------------------------------------------------------------------- +proc generic::FindWindowWithCommonTypes { win typelist } { + set toplevel [winfo toplevel $win] + while {![string equal $win $toplevel]} { + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + set win [winfo parent $win] + } + ## We have reached the toplevel, which may be also a target (SF Bug #30) + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + return { {} {} {} } +};# generic::FindWindowWithCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDroppedData +# ---------------------------------------------------------------------------- +proc generic::GetDroppedData { time } { + variable _dropped_data + return $_dropped_data +};# generic::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::SetDroppedData +# ---------------------------------------------------------------------------- +proc generic::SetDroppedData { data } { + variable _dropped_data + set _dropped_data $data +};# generic::SetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSource +# ---------------------------------------------------------------------------- +proc generic::GetDragSource { } { + variable _drag_source + return $_drag_source +};# generic::GetDragSource + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTarget +# ---------------------------------------------------------------------------- +proc generic::GetDropTarget { } { + variable _drop_target + return $_drop_target +};# generic::GetDropTarget + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDragSourceCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTargetCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDropTargetCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDropTargetCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_types +# ---------------------------------------------------------------------------- +proc generic::platform_specific_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_specific_type $type]] + } + return $new_types +}; # generic::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_type +# ---------------------------------------------------------------------------- +proc generic::platform_specific_type { type } { + variable _tkdnd2platform + if {[dict exists $_tkdnd2platform $type]} { + return [dict get $_tkdnd2platform $type] + } + list $type +}; # generic::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_types +# ---------------------------------------------------------------------------- +proc generic::platform_independent_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_independent_type $type]] + } + return $new_types +}; # generic::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_type +# ---------------------------------------------------------------------------- +proc generic::platform_independent_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return [dict get $_platform2tkdnd $type] + } + return $type +}; # generic::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command generic::supported_types +# ---------------------------------------------------------------------------- +proc generic::supported_types { types } { + set new_types {} + foreach type $types { + if {[supported_type $type]} {lappend new_types $type} + } + return $new_types +}; # generic::supported_types + +# ---------------------------------------------------------------------------- +# Command generic::supported_type +# ---------------------------------------------------------------------------- +proc generic::supported_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return 1 + } + return 0 +}; # generic::supported_type diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_macosx.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_macosx.tcl new file mode 100644 index 0000000000000000000000000000000000000000..307f6da2e94286d01dc9e068fffebe46de3c43f3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_macosx.tcl @@ -0,0 +1,144 @@ +# +# tkdnd_macosx.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. + +# This software is copyrighted by: +# Georgios Petasis, Athens, Greece. +# e-mail: petasisg@yahoo.gr, petasis@iit.demokritos.gr +# +# Mac portions (c) 2009 Kevin Walzer/WordTech Communications LLC, +# kw@codebykevin.com +# +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +#basic API for Mac Drag and Drop + +#two data types supported: strings and file paths + +#two commands at C level: ::tkdnd::macdnd::registerdragwidget, ::tkdnd::macdnd::unregisterdragwidget + +#data retrieval mechanism: text or file paths are copied from drag clipboard to system clipboard and retrieved via [clipboard get]; array of file paths is converted to single tab-separated string, can be split into Tcl list + +if {[tk windowingsystem] eq "aqua" && "AppKit" ni [winfo server .]} { + error {TkAqua Cocoa required} +} + +namespace eval macdnd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + NSPasteboardTypeString DND_Text \ + NSFilenamesPboardType DND_Files \ + NSPasteboardTypeHTML DND_HTML \ + ] + };# initialise + +};# namespace macdnd + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleEnter +# ---------------------------------------------------------------------------- +proc macdnd::HandleEnter { path drag_source typelist { data {} } } { + variable _pressedkeys + variable _actionlist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# macdnd::HandleEnter + +# ---------------------------------------------------------------------------- +# Command macdnd::HandlePosition +# ---------------------------------------------------------------------------- +proc macdnd::HandlePosition { drop_target rootX rootY {drag_source {}} } { + variable _pressedkeys + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# macdnd::HandlePosition + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleLeave +# ---------------------------------------------------------------------------- +proc macdnd::HandleLeave { args } { + ::tkdnd::generic::HandleLeave +};# macdnd::HandleLeave + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleDrop +# ---------------------------------------------------------------------------- +proc macdnd::HandleDrop { drop_target data args } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y 0 +};# macdnd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command macdnd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc macdnd::GetDragSourceCommonTypes { } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# macdnd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # macdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # macdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # macdnd::platform_independent_type diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_unix.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_unix.tcl new file mode 100644 index 0000000000000000000000000000000000000000..4446f21c9b55ddb174d3891998f907a109c4a2df --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_unix.tcl @@ -0,0 +1,883 @@ +# +# tkdnd_unix.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval xdnd { + variable _dragging 0 + + proc debug { msg } { + tkdnd::debug $msg + };# debug + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + text/plain\;charset=utf-8 DND_Text \ + UTF8_STRING DND_Text \ + text/plain DND_Text \ + STRING DND_Text \ + TEXT DND_Text \ + COMPOUND_TEXT DND_Text \ + text/uri-list DND_Files \ + text/html\;charset=utf-8 DND_HTML \ + text/html DND_HTML \ + application/x-color DND_Color \ + ] + };# initialise + +};# namespace xdnd + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::GetPressedKeys { drop_target } { + #DBG debug "xdnd::GetPressedKeys: $drop_target" + if {[catch {set dict [_keyboard_get_state $drop_target]}]} { + return {} + } + set pressedkeys {} + for {set b 1} {$b <= 5} {incr b} { + if {[dict get $dict $b]} {lappend pressedkeys $b} + } + foreach {k l} {Alt alt Shift shift Control ctrl Lock caps_lock + Mod1 mod1 Mod2 mod2 Mod3 mod3 Mod4 mod4 Mod5 mod5} { + if {[dict get $dict $k]} {lappend pressedkeys $l} + } + #DBG debug "xdnd::GetPressedKeys: $drop_target -> $pressedkeys" + return $pressedkeys +};# xdnd::GetPressedKeys + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndEnter { drop_target drag_source typelist time + { data {} } } { + variable _pressedkeys + variable _actionlist + variable _typelist + set _pressedkeys [GetPressedKeys $drop_target] + set _actionlist { copy move link ask private } + set _typelist $typelist + #DBG debug "xdnd::HandleXdndEnter: $time" + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $drop_target $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# xdnd::HandleXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndPosition { drop_target rootX rootY time + { drag_source {} } { action default } } { + variable _pressedkeys + variable _typelist + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + set _pressedkeys [GetPressedKeys $drop_target] + #DBG debug "xdnd::HandleXdndPosition: $time" + ## Get the dropped data... + catch { + ::tkdnd::generic::SetDroppedData [GetPositionData $drop_target $_typelist $time] + } + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY $action +};# xdnd::HandleXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndLeave { } { + #DBG debug "xdnd::HandleXdndLeave" + ::tkdnd::generic::HandleLeave +};# xdnd::HandleXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndDrop { time } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + set _pressedkeys [GetPressedKeys [::tkdnd::generic::GetDropTarget]] + #DBG debug "xdnd::HandleXdndDrop: $time" + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData [GetDroppedData \ + [::tkdnd::generic::GetDragSource] [::tkdnd::generic::GetDropTarget] \ + [::tkdnd::generic::GetDragSourceCommonTypes] $time] + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y $time +};# xdnd::HandleXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::GetPositionData +# ---------------------------------------------------------------------------- +proc xdnd::GetPositionData { drop_target typelist time } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + GetDroppedData [::tkdnd::generic::GetDragSource] $drop_target \ + $common_drag_source_types $time +};# xdnd::GetPositionData + +# ---------------------------------------------------------------------------- +# Command xdnd::GetDroppedData +# ---------------------------------------------------------------------------- +proc xdnd::GetDroppedData { _drag_source _drop_target _common_drag_source_types time } { + if {![llength $_common_drag_source_types]} { + return -code error "no common data types between the drag source and drop target widgets" + } + ## Is drag source in this application? + if {[catch {winfo pathname -displayof $_drop_target $_drag_source} p]} { + set _use_tk_selection 0 + } else { + set _use_tk_selection 1 + } + foreach type $_common_drag_source_types { + #DBG debug "TYPE: $type ($_drop_target)" + # _get_selection $_drop_target $time $type + if {$_use_tk_selection} { + if {![catch { + selection get -displayof $_drop_target -selection XdndSelection \ + -type $type + } result options]} { + return [normalise_data $type $result] + } + } else { + #DBG debug "_selection_get -displayof $_drop_target -selection XdndSelection \ + # -type $type -time $time" + #after 100 [list focus -force $_drop_target] + #after 50 [list raise [winfo toplevel $_drop_target]] + if {![catch { + _selection_get -displayof $_drop_target -selection XdndSelection \ + -type $type -time $time + } result options]} { + return [normalise_data $type $result] + } + } + } + return -options $options $result +};# xdnd::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # xdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # xdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # xdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command xdnd::_normalise_data +# ---------------------------------------------------------------------------- +proc xdnd::normalise_data { type data } { + # Tk knows how to interpret the following types: + # STRING, TEXT, COMPOUND_TEXT + # UTF8_STRING + # Else, it returns a list of 8 or 32 bit numbers... + switch -glob $type { + STRING - UTF8_STRING - TEXT - COMPOUND_TEXT {return $data} + text/html { + if {[catch { + encoding convertfrom unicode $data + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/html\;charset=utf-8 - + text/plain\;charset=utf-8 - + text/plain { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/uri-list* { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + ## Get rid of \r\n + set string [string trim [string map {\r\n \n} $string]] + set files {} + foreach quoted_file [split $string] { + set file [tkdnd::urn_unquote $quoted_file] + switch -glob $file { + \#* {} + file://* {lappend files [string range $file 7 end]} + ftp://* - + https://* - + http://* {lappend files $quoted_file} + default {lappend files $file} + } + } + return $files + } + application/x-color { + return $data + } + text/x-moz-url - + application/q-iconlist - + default {return $data} + } +}; # xdnd::normalise_data + +############################################################################# +## +## XDND drag implementation +## +############################################################################# + +# ---------------------------------------------------------------------------- +# Command xdnd::_selection_ownership_lost +# ---------------------------------------------------------------------------- +proc xdnd::_selection_ownership_lost {} { + variable _dragging + set _dragging 0 +};# _selection_ownership_lost + +# ---------------------------------------------------------------------------- +# Command xdnd::_dodragdrop +# ---------------------------------------------------------------------------- +proc xdnd::_dodragdrop { source actions types data button { cursor_map {} } } { + variable _dragging + + #DBG debug "xdnd::_dodragdrop: source: $source, actions: $actions, types: $types,\ + #DBG data: \"$data\", button: $button" + if {$_dragging} { + ## We are in the middle of another drag operation... + error "another drag operation in progress" + } + + variable _dodragdrop_drag_source $source + variable _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_proxy 0 + variable _dodragdrop_actions $actions + variable _dodragdrop_action_descriptions $actions + variable _dodragdrop_actions_len [llength $actions] + variable _dodragdrop_types $types + variable _dodragdrop_types_len [llength $types] + variable _dodragdrop_data $data + variable _dodragdrop_transfer_data {} + variable _dodragdrop_button $button + variable _dodragdrop_time 0 + variable _dodragdrop_default_action refuse_drop + variable _dodragdrop_waiting_status 0 + variable _dodragdrop_drop_target_accepts_drop 0 + variable _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_current_cursor $_dodragdrop_default_action + variable _dodragdrop_drop_occured 0 + variable _dodragdrop_selection_requestor 0 + variable _dodragdrop_cursor_map $cursor_map + + ## + ## If we have more than 3 types, the property XdndTypeList must be set on + ## the drag source widget... + ## + if {$_dodragdrop_types_len > 3} { + _announce_type_list $_dodragdrop_drag_source $_dodragdrop_types + } + + ## + ## Announce the actions & their descriptions on the XdndActionList & + ## XdndActionDescription properties... + ## + _announce_action_list $_dodragdrop_drag_source $_dodragdrop_actions \ + $_dodragdrop_action_descriptions + + ## + ## Arrange selection handlers for our drag source, and all the supported types + ## + #DBG debug "xdnd::_dodragdrop: registerSelectionHandler $source $types" + registerSelectionHandler $source $types + + ## + ## Step 1: When a drag begins, the source takes ownership of XdndSelection. + ## + #DBG debug "xdnd::_dodragdrop: selection own $source" + selection own -command ::tkdnd::xdnd::_selection_ownership_lost \ + -selection XdndSelection $source + set _dragging 1 + + ## Grab the mouse pointer... + #DBG debug "xdnd::_dodragdrop: _grab_pointer $source [_get_mapped_cursor $_dodragdrop_default_action]" + _grab_pointer $source [_get_mapped_cursor $_dodragdrop_default_action] + + ## Register our generic event handler... + # The generic event callback will report events by modifying variable + # ::xdnd::_dodragdrop_event: a dict with event information will be set as + # the value of the variable... + #DBG debug "xdnd::_dodragdrop: _register_generic_event_handler" + _register_generic_event_handler + + ## Set a timeout for debugging purposes... + # after 60000 {set ::tkdnd::xdnd::_dragging 0} + + #DBG debug "xdnd::_dodragdrop: waiting drag action to finish..." + tkwait variable ::tkdnd::xdnd::_dragging + #DBG debug "xdnd::_dodragdrop: drag action finished!" + _SendXdndLeave + + set _dragging 0 + #DBG debug "xdnd::_dodragdrop: _ungrab_pointer $source" + _ungrab_pointer $source + #DBG debug "xdnd::_dodragdrop: _unregister_generic_event_handler" + _unregister_generic_event_handler + catch {selection clear -selection XdndSelection} + #DBG debug "xdnd::_dodragdrop: unregisterSelectionHandler $source $types" + unregisterSelectionHandler $source $types + return $_dodragdrop_drop_target_accepts_action +};# xdnd::_dodragdrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_process_drag_events +# ---------------------------------------------------------------------------- +proc xdnd::_process_drag_events {event} { + # The return value from proc is normally 0. A non-zero return value indicates + # that the event is not to be handled further; that is, proc has done all + # processing that is to be allowed for the event + variable _dragging + if {!$_dragging} {return 0} + #DBG debug "xdnd::_process_drag_events: $event" + + variable _dodragdrop_time + set time [dict get $event time] + set type [dict get $event type] + if {$time < $_dodragdrop_time && ![string equal $type SelectionRequest]} { + #DBG debug "xdnd::_process_drag_events: return 0 (1)" + return 0 + } + set _dodragdrop_time $time + + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_default_action + switch $type { + MotionNotify { + set rootx [dict get $event x_root] + set rooty [dict get $event y_root] + set window [_find_drop_target_window $_dodragdrop_drag_source \ + $rootx $rooty] + if {[string length $window]} { + ## Examine the modifiers to suggest an action... + set _dodragdrop_default_action [_default_action $event] + ## Is it a Tk widget? + #DBG set path [winfo containing $rootx $rooty] + #DBG debug "Window under mouse: $window ($path)" + if {$_dodragdrop_drop_target != $window} { + ## Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + ## Is there a proxy? If not, _find_drop_target_proxy returns the + ## target window, so we always get a valid "proxy". + set proxy [_find_drop_target_proxy $_dodragdrop_drag_source $window] + ## Send XdndEnter to $window + _SendXdndEnter $window $proxy + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } else { + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } + } else { + ## No window under the mouse. Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + } + } + ButtonPress { + } + ButtonRelease { + variable _dodragdrop_button + set button [dict get $event button] + if {$button == $_dodragdrop_button} { + ## The button that initiated the drag was released. Trigger drop... + #DBG debug "xdnd::_process_drag_events: _SendXdndDrop" + _SendXdndDrop + } + #DBG debug "xdnd::_process_drag_events: return 1 (2)" + # return 1 ;# Returning non-zero is not a good idea... + return 0 + } + KeyPress { + } + KeyRelease { + set keysym [dict get $event keysym] + switch $keysym { + Escape { + ## The user has pressed escape. Abort... + if {$_dragging} {set _dragging 0} + } + } + } + SelectionRequest { + variable _dodragdrop_selection_requestor + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + set _dodragdrop_selection_requestor [dict get $event requestor] + set _dodragdrop_selection_property [dict get $event property] + set _dodragdrop_selection_selection [dict get $event selection] + set _dodragdrop_selection_target [dict get $event target] + set _dodragdrop_selection_time $time + #DBG debug "xdnd::_process_drag_events: return 0 (3)" + return 0 + } + default { + #DBG debug "xdnd::_process_drag_events: return 0 (4)" + return 0 + } + } + #DBG debug "xdnd::_process_drag_events: return 0 (5)" + return 0 +};# _process_drag_events + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndEnter {window proxy} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_types + variable _dodragdrop_waiting_status + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_target > 0} _SendXdndLeave + if {$_dodragdrop_drop_occured} return + set _dodragdrop_drop_target $window + set _dodragdrop_drop_target_proxy $proxy + set _dodragdrop_waiting_status 0 + if {$_dodragdrop_drop_target < 1} return + #DBG debug "XdndEnter: $_dodragdrop_drop_target $_dodragdrop_drop_target_proxy" + _send_XdndEnter $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $_dodragdrop_types +};# xdnd::_SendXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndPosition {rootx rooty action} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_waiting_status + ## Arrange a new XdndPosition, to be send periodically... + variable _dodragdrop_xdnd_position_heartbeat + catch {after cancel $_dodragdrop_xdnd_position_heartbeat} + set _dodragdrop_xdnd_position_heartbeat [after 200 \ + [list ::tkdnd::xdnd::_SendXdndPosition $rootx $rooty $action]] + if {$_dodragdrop_waiting_status} {return} + #DBG debug "XdndPosition: $_dodragdrop_drop_target $rootx $rooty $action" + _send_XdndPosition $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $rootx $rooty $action + set _dodragdrop_waiting_status 1 +};# xdnd::_SendXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndStatus +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndStatus {event} { + variable _dodragdrop_drop_target + variable _dodragdrop_waiting_status + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_waiting_status 0 + foreach key {target accept want_position action x y w h} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor + #DBG debug "XdndStatus: $event" +};# xdnd::_HandleXdndStatus + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndFinished +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndFinished {event} { + variable _dodragdrop_xdnd_finished_event_after_id + catch {after cancel $_dodragdrop_xdnd_finished_event_after_id} + set _dodragdrop_xdnd_finished_event_after_id {} + variable _dodragdrop_drop_target + set _dodragdrop_drop_target 0 + variable _dragging + if {$_dragging} {set _dragging 0} + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + if {[dict size $event]} { + foreach key {target accept action} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + } else { + set _dodragdrop_drop_target_accepts_drop 0 + } + if {!$_dodragdrop_drop_target_accepts_drop} { + set _dodragdrop_drop_target_accepts_action refuse_drop + } + #DBG debug "XdndFinished: $event" +};# xdnd::_HandleXdndFinished + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndLeave {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_target_proxy + #DBG debug "XdndLeave: $_dodragdrop_drop_target" + _send_XdndLeave $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy + set _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_drop_target_accepts_drop 0 + set _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor +};# xdnd::_SendXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndDrop {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} { + ## The mouse has been released over a widget that does not accept drops. + _HandleXdndFinished {} + return + } + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} {return} + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + set _dodragdrop_drop_occured 1 + _update_cursor clock + + if {!$_dodragdrop_drop_target_accepts_drop} { + _SendXdndLeave + _HandleXdndFinished {} + return + } + #DBG debug "XdndDrop: $_dodragdrop_drop_target" + variable _dodragdrop_drop_timestamp + set _dodragdrop_drop_timestamp [_send_XdndDrop \ + $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy] + set _dodragdrop_drop_target 0 + #DBG debug "XdndDrop: $_dodragdrop_drop_target" + ## Arrange a timeout for receiving XdndFinished... + variable _dodragdrop_xdnd_finished_event_after_id + set _dodragdrop_xdnd_finished_event_after_id \ + [after 10000 [list ::tkdnd::xdnd::_HandleXdndFinished {}]] +};# xdnd::_SendXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_update_cursor +# ---------------------------------------------------------------------------- +proc xdnd::_update_cursor { {cursor {}}} { + #DBG debug "_update_cursor $cursor" + variable _dodragdrop_current_cursor + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + if {![string length $cursor]} { + set cursor refuse_drop + if {$_dodragdrop_drop_target_accepts_drop} { + set cursor $_dodragdrop_drop_target_accepts_action + } + } + if {![string equal $cursor $_dodragdrop_current_cursor]} { + _set_pointer_cursor $_dodragdrop_drag_source [_get_mapped_cursor $cursor] + set _dodragdrop_current_cursor $cursor + } +};# xdnd::_update_cursor + +# ---------------------------------------------------------------------------- +# Command xdnd::_get_mapped_cursor +# ---------------------------------------------------------------------------- +proc xdnd::_get_mapped_cursor { cursor } { + variable _dodragdrop_cursor_map + variable _dodragdrop_drag_source + ## Is there a custom cursor map? + if {[catch {dict get $_dodragdrop_cursor_map $cursor} mapped]} { + ## Do not report the error, ignore the mapping. + set mapped $cursor + } + ## Is there a cursor feedback command? + set cmd [bind $_dodragdrop_drag_source <>] + if {$cmd ne ""} { + set code [catch {uplevel \#0 $cmd \{$_dodragdrop_drag_source\} \{$cursor\} \{$mapped\}} info options] + #DBG debug "CODE: $code ---- $info" + switch -exact -- $code { + 0 {if {$info ne ""} {set mapped $info}} + default { + return -options $options $info + } + } + } + return $mapped +};# xdnd::_get_mapped_cursor + +# ---------------------------------------------------------------------------- +# Command xdnd::_default_action +# ---------------------------------------------------------------------------- +proc xdnd::_default_action {event} { + variable _dodragdrop_actions + variable _dodragdrop_actions_len + if {$_dodragdrop_actions_len == 1} {return [lindex $_dodragdrop_actions 0]} + + set alt [dict get $event Alt] + set shift [dict get $event Shift] + set control [dict get $event Control] + + if {$shift && $control && [lsearch $_dodragdrop_actions link] != -1} { + return link + } elseif {$control && [lsearch $_dodragdrop_actions copy] != -1} { + return copy + } elseif {$shift && [lsearch $_dodragdrop_actions move] != -1} { + return move + } elseif {$alt && [lsearch $_dodragdrop_actions link] != -1} { + return link + } + return default +};# xdnd::_default_action + +# ---------------------------------------------------------------------------- +# Command xdnd::getFormatForType +# ---------------------------------------------------------------------------- +proc xdnd::getFormatForType {type} { + switch -glob [string tolower $type] { + text/plain\;charset=utf-8 - + text/html\;charset=utf-8 - + utf8_string {set format UTF8_STRING} + text/html - + text/plain - + string - + text - + compound_text {set format STRING} + text/uri-list* {set format UTF8_STRING} + application/x-color {set format $type} + default {set format $type} + } + return $format +};# xdnd::getFormatForType + +# ---------------------------------------------------------------------------- +# Command xdnd::registerSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::registerSelectionHandler {source types} { + foreach type $types { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source [list ::tkdnd::xdnd::_SendData $type] + } +};# xdnd::registerSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::unregisterSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::unregisterSelectionHandler {source types} { + foreach type $types { + catch { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source {} + } + } +};# xdnd::unregisterSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::_convert_to_unsigned +# ---------------------------------------------------------------------------- +proc xdnd::_convert_to_unsigned {data format} { + switch $format { + 8 { set mask 0xff } + 16 { set mask 0xffff } + 32 { set mask 0xffffff } + default {error "unsupported format $format"} + } + ## Convert signed integer into unsigned... + set d [list] + foreach num $data { + lappend d [expr { $num & $mask }] + } + return $d +};# xdnd::_convert_to_unsigned + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendData +# ---------------------------------------------------------------------------- +proc xdnd::_SendData {type offset bytes args} { + variable _dodragdrop_drag_source + variable _dodragdrop_types + variable _dodragdrop_data + variable _dodragdrop_transfer_data + + ## The variable _dodragdrop_data contains a list of data, one for each + ## type in the _dodragdrop_types variable. We have to search types, and find + ## the corresponding entry in the _dodragdrop_data list. + set index [lsearch $_dodragdrop_types $type] + if {$index < 0} { + error "unable to locate data suitable for type \"$type\"" + } + set typed_data [lindex $_dodragdrop_data $index] + set format 8 + if {$offset == 0} { + ## Prepare the data to be transferred... + switch -glob $type { + text/plain* - UTF8_STRING - STRING - TEXT - COMPOUND_TEXT { + binary scan [encoding convertto utf-8 $typed_data] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + text/uri-list* { + set files [list] + foreach file $typed_data { + switch -glob $file { + *://* {lappend files $file} + default {lappend files file://$file} + } + } + binary scan [encoding convertto utf-8 "[join $files \r\n]\r\n"] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + application/x-color { + set format 16 + ## Try to understand the provided data: we accept a standard Tk colour, + ## or a list of 3 values (red green blue) or a list of 4 values + ## (red green blue opacity). + switch [llength $typed_data] { + 1 { set color [winfo rgb $_dodragdrop_drag_source $typed_data] + lappend color 65535 } + 3 { set color $typed_data; lappend color 65535 } + 4 { set color $typed_data } + default {error "unknown color data: \"$typed_data\""} + } + ## Convert the 4 elements into 16 bit values... + set _dodragdrop_transfer_data [list] + foreach c $color { + lappend _dodragdrop_transfer_data [format 0x%04X $c] + } + } + default { + set format 32 + binary scan $typed_data c* _dodragdrop_transfer_data + } + } + } + + ## + ## Data has been split into bytes. Count the bytes requested, and return them + ## + set data [lrange $_dodragdrop_transfer_data $offset [expr {$offset+$bytes-1}]] + switch $format { + 8 { + set data [encoding convertfrom utf-8 [binary format c* $data]] + } + 16 { + variable _dodragdrop_selection_requestor + if {$_dodragdrop_selection_requestor} { + ## Tk selection cannot process this format (only 8 & 32 supported). + ## Call our XChangeProperty... + set numItems [llength $data] + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + XChangeProperty $_dodragdrop_drag_source \ + $_dodragdrop_selection_requestor \ + $_dodragdrop_selection_property \ + $_dodragdrop_selection_target \ + $format \ + $_dodragdrop_selection_time \ + $data $numItems + return -code break + } + } + 32 { + } + default { + error "unsupported format $format" + } + } + #DBG debug "SendData: $type $offset $bytes $args ($typed_data)" + #DBG debug " $data" + return $data +};# xdnd::_SendData diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_utils.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_utils.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ef1e50266805dae1fe37fa22f1572963387938c8 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_utils.tcl @@ -0,0 +1,256 @@ +# +# tkdnd_utils.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require tkdnd +namespace eval ::tkdnd { + namespace eval utils { + };# namespace ::tkdnd::utils + namespace eval text { + variable _drag_tag tkdnd::drag::selection::tag + variable _state {} + variable _drag_source_widget {} + variable _drop_target_widget {} + variable _now_dragging 0 + };# namespace ::tkdnd::text +};# namespace ::tkdnd + +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag clear 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag motion 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_TextAutoScan %W %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag reset 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag clear 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag motion 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag reset 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag clear 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag motion 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag reset 3 %W %s %X %Y %x %y} + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drag_source { mode path { types DND_Text } { event 1 } { tagprefix TkDND_Drag_Text } { tag sel } } { + switch -exact -- $mode { + register { + $path tag bind $tag \ + [list tkdnd::text::_begin_drag press ${event} %W %s %X %Y %x %y] + ## Set a binding to the widget, to put selection as data... + bind $path <> \ + [list ::tkdnd::text::DragInitCmd $path %t $tag] + ## Set a binding to the widget, to remove selection if action is move... + bind $path <> \ + [list ::tkdnd::text::DragEndCmd $path %A $tag] + } + unregister { + $path tag bind $tag {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drag_source $mode $path $types $event $tagprefix +};# ::tkdnd::text::drag_source + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drop_target { mode path { types DND_Text } } { + switch -exact -- $mode { + register { + bind $path <> \ + [list ::tkdnd::text::DropPosition $path %X %Y %A %a %m] + bind $path <> \ + [list ::tkdnd::text::Drop $path %D %X %Y %A %a %m] + } + unregister { + bind $path <> {} + bind $path <> {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drop_target $mode $path $types +};# ::tkdnd::text::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragInitCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragInitCmd { path { types DND_Text } { tag sel } { actions { copy move } } } { + ## Save the selection indices... + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget $path + set _drop_target_widget {} + _save_selection $path $tag + list $actions $types [$path get $tag.first $tag.last] +};# ::tkdnd::text::DragInitCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragEndCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragEndCmd { path action { tag sel } } { + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget {} + set _drop_target_widget {} + _restore_selection $path $tag + switch -exact -- $action { + move { + ## Delete the original selected text... + variable _selection_first + variable _selection_last + $path delete $_selection_first $_selection_last + } + } +};# ::tkdnd::text::DragEndCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DropPosition +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DropPosition { path X Y action actions keys} { + variable _drag_source_widget + variable _drop_target_widget + set _drop_target_widget $path + ## This check is primitive, a more accurate one is needed! + if {$path eq $_drag_source_widget} { + ## This is a drag within the same widget! Set action to move... + if {"move" in $actions} {set action move} + } + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y; update + return $action +};# ::tkdnd::text::DropPosition + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::Drop +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::Drop { path data X Y action actions keys } { + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y + $path insert [$path index insert] $data + return $action +};# ::tkdnd::text::Drop + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_save_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_save_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + variable _selection_tag $tag + set _selection_first [$path index $tag.first] + set _selection_last [$path index $tag.last] + $path tag add $_drag_tag $_selection_first $_selection_last + $path tag configure $_drag_tag \ + -background [$path tag cget $tag -background] \ + -foreground [$path tag cget $tag -foreground] +};# tkdnd::text::_save_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_restore_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_restore_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + $path tag delete $_drag_tag + $path tag remove $tag 0.0 end + #$path tag add $tag $_selection_first $_selection_last +};# tkdnd::text::_restore_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_begin_drag { event button source state X Y x y } { + variable _drop_target_widget + variable _state + # puts "::tkdnd::text::_begin_drag $event $button $source $state $X $Y $x $y" + + switch -exact -- $event { + clear { + switch -exact -- $_state { + press { + ## Do not execute other bindings, as they will erase selection... + return -code break + } + } + set _state clear + } + motion { + variable _now_dragging + if {$_now_dragging} {return -code break} + if { [string equal $_state "press"] } { + variable _x0; variable _y0 + if { abs($_x0-$X) > ${::tkdnd::_dx} || abs($_y0-$Y) > ${::tkdnd::_dy} } { + set _state "done" + set _drop_target_widget {} + set _now_dragging 1 + set code [catch { + ::tkdnd::_init_drag $button $source $state $X $Y $x $y + } info options] + set _drop_target_widget {} + set _now_dragging 0 + if {$code != 0} { + ## Something strange occurred... + return -options $options $info + } + } + return -code break + } + set _state clear + } + press { + variable _x0; variable _y0 + set _x0 $X + set _y0 $Y + set _state "press" + } + reset { + set _state {} + } + } + if {$source eq $_drop_target_widget} {return -code break} + return -code continue +};# tkdnd::text::_begin_drag + +proc ::tkdnd::text::_TextAutoScan {w x y} { + variable _now_dragging + if {$_now_dragging} {return -code break} + return -code continue +};# tkdnd::text::_TextAutoScan diff --git a/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_windows.tcl b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_windows.tcl new file mode 100644 index 0000000000000000000000000000000000000000..a1d01f3a2c438eaf3f676437d4d4ba89b3ba64f0 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/osx_arm/tkdnd_windows.tcl @@ -0,0 +1,167 @@ +# +# tkdnd_windows.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval olednd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + CF_UNICODETEXT DND_Text \ + CF_TEXT DND_Text \ + CF_HDROP DND_Files \ + UniformResourceLocator DND_URL \ + CF_HTML DND_HTML \ + {HTML Format} DND_HTML \ + CF_RTF DND_RTF \ + CF_RTFTEXT DND_RTF \ + {Rich Text Format} DND_RTF \ + ] + # FileGroupDescriptorW DND_Files \ + # FileGroupDescriptor DND_Files \ + + ## Mapping from TkDND types to platform types... + ::tkdnd::generic::initialise_tkdnd_to_platform_types [list \ + DND_Text {CF_UNICODETEXT CF_TEXT} \ + DND_Files {CF_HDROP} \ + DND_URL {UniformResourceLocator UniformResourceLocatorW} \ + DND_HTML {CF_HTML {HTML Format}} \ + DND_RTF {CF_RTF CF_RTFTEXT {Rich Text Format}} \ + ] + };# initialise + +};# namespace olednd + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragEnter +# ---------------------------------------------------------------------------- +proc olednd::HandleDragEnter { drop_target typelist actionlist pressedkeys + rootX rootY codelist { data {} } } { + ::tkdnd::generic::SetDroppedData $data + focus $drop_target + ::tkdnd::generic::HandleEnter $drop_target 0 $typelist \ + $codelist $actionlist $pressedkeys + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragEnter + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragOver +# ---------------------------------------------------------------------------- +proc olednd::HandleDragOver { drop_target pressedkeys rootX rootY } { + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragOver + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragLeave +# ---------------------------------------------------------------------------- +proc olednd::HandleDragLeave { drop_target } { + ::tkdnd::generic::HandleLeave + if {$::tkdnd::_auto_update} {update idletasks} +};# olednd::HandleDragLeave + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDrop +# ---------------------------------------------------------------------------- +proc olednd::HandleDrop { drop_target pressedkeys rootX rootY type data } { + ::tkdnd::generic::SetDroppedData [normalise_data $type $data] + set action [::tkdnd::generic::HandleDrop $drop_target {} \ + $pressedkeys $rootX $rootY 0] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command olednd::GetDataType +# ---------------------------------------------------------------------------- +proc olednd::GetDataType { drop_target typelist } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + lindex $common_drag_source_types 0 +};# olednd::GetDataType + +# ---------------------------------------------------------------------------- +# Command olednd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc olednd::GetDragSourceCommonTypes { drop_target } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# olednd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_types +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # olednd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_type +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # olednd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_independent_type +# ---------------------------------------------------------------------------- +proc olednd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # olednd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command olednd::normalise_data +# ---------------------------------------------------------------------------- +proc olednd::normalise_data { type data } { + switch [lindex [::tkdnd::generic::platform_independent_type $type] 0] { + DND_Text {return $data} + DND_Files {return $data} + DND_HTML {return [encoding convertfrom utf-8 $data]} + default {return $data} + } +}; # olednd::normalise_data diff --git a/gui_data/tkinterdnd2/tkdnd/win64/libtkdnd2.9.2.dll b/gui_data/tkinterdnd2/tkdnd/win64/libtkdnd2.9.2.dll new file mode 100644 index 0000000000000000000000000000000000000000..c9cc5abbed923f273a5d22ca7590e45e771b11b5 Binary files /dev/null and b/gui_data/tkinterdnd2/tkdnd/win64/libtkdnd2.9.2.dll differ diff --git a/gui_data/tkinterdnd2/tkdnd/win64/pkgIndex.tcl b/gui_data/tkinterdnd2/tkdnd/win64/pkgIndex.tcl new file mode 100644 index 0000000000000000000000000000000000000000..733ae7d328e59ecd3e70d7a421e4277a29884723 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/pkgIndex.tcl @@ -0,0 +1,7 @@ +package ifneeded tkdnd 2.9.2 \ + "source \{$dir/tkdnd.tcl\} ; \ + tkdnd::initialise \{$dir\} libtkdnd2.9.2[info sharedlibextension] tkdnd" + +package ifneeded tkdnd::utils 2.9.2 \ + "source \{$dir/tkdnd_utils.tcl\} ; \ + package provide tkdnd::utils 2.9.2" \ No newline at end of file diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd.tcl new file mode 100644 index 0000000000000000000000000000000000000000..12d1dd289de6b78e83922a1b1653ef6165dc70db --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd.tcl @@ -0,0 +1,469 @@ +# +# tkdnd.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require Tk + +namespace eval ::tkdnd { + variable _topw ".drag" + variable _tabops + variable _state + variable _x0 + variable _y0 + variable _platform_namespace + variable _drop_file_temp_dir + variable _auto_update 1 + variable _dx 3 ;# The difference in pixels before a drag is initiated. + variable _dy 3 ;# The difference in pixels before a drag is initiated. + + variable _windowingsystem + + bind TkDND_Drag1 {tkdnd::_begin_drag press 1 %W %s %X %Y %x %y} + bind TkDND_Drag1 {tkdnd::_begin_drag motion 1 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag press 2 %W %s %X %Y %x %y} + bind TkDND_Drag2 {tkdnd::_begin_drag motion 2 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag press 3 %W %s %X %Y %x %y} + bind TkDND_Drag3 {tkdnd::_begin_drag motion 3 %W %s %X %Y %x %y} + + # ---------------------------------------------------------------------------- + # Command tkdnd::initialise: Initialise the TkDND package. + # ---------------------------------------------------------------------------- + proc initialise { dir PKG_LIB_FILE PACKAGE_NAME} { + variable _platform_namespace + variable _drop_file_temp_dir + variable _windowingsystem + global env + + switch [tk windowingsystem] { + x11 { + set _windowingsystem x11 + } + win32 - + windows { + set _windowingsystem windows + } + aqua { + set _windowingsystem aqua + } + default { + error "unknown Tk windowing system" + } + } + + ## Get User's home directory: We try to locate the proper path from a set of + ## environmental variables... + foreach var {HOME HOMEPATH USERPROFILE ALLUSERSPROFILE APPDATA} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)]} { + set UserHomeDir $env($var) + break + } + } + } + + ## Should use [tk windowingsystem] instead of tcl platform array: + ## OS X returns "unix," but that's not useful because it has its own + ## windowing system, aqua + ## Under windows we have to also combine HOMEDRIVE & HOMEPATH... + if {![info exists UserHomeDir] && + [string equal $_windowingsystem windows] && + [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { + if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { + set UserHomeDir $env(HOMEDRIVE)$env(HOMEPATH) + } + } + ## Have we located the needed path? + if {![info exists UserHomeDir]} { + set UserHomeDir [pwd] + } + set UserHomeDir [file normalize $UserHomeDir] + + ## Try to locate a temporary directory... + foreach var {TKDND_TEMP_DIR TEMP TMP} { + if {[info exists env($var)]} { + if {[file isdirectory $env($var)] && [file writable $env($var)]} { + set _drop_file_temp_dir $env($var) + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + foreach _dir [list "$UserHomeDir/Local Settings/Temp" \ + "$UserHomeDir/AppData/Local/Temp" \ + /tmp \ + C:/WINDOWS/Temp C:/Temp C:/tmp \ + D:/WINDOWS/Temp D:/Temp D:/tmp] { + if {[file isdirectory $_dir] && [file writable $_dir]} { + set _drop_file_temp_dir $_dir + break + } + } + } + if {![info exists _drop_file_temp_dir]} { + set _drop_file_temp_dir $UserHomeDir + } + set _drop_file_temp_dir [file native $_drop_file_temp_dir] + + source $dir/tkdnd_generic.tcl + switch $_windowingsystem { + x11 { + source $dir/tkdnd_unix.tcl + set _platform_namespace xdnd + } + win32 - + windows { + source $dir/tkdnd_windows.tcl + set _platform_namespace olednd + } + aqua { + source $dir/tkdnd_macosx.tcl + set _platform_namespace macdnd + } + default { + error "unknown Tk windowing system" + } + } + load $dir/$PKG_LIB_FILE $PACKAGE_NAME + source $dir/tkdnd_compat.tcl + ${_platform_namespace}::initialise + };# initialise + + proc GetDropFileTempDirectory { } { + variable _drop_file_temp_dir + return $_drop_file_temp_dir + } + proc SetDropFileTempDirectory { dir } { + variable _drop_file_temp_dir + set _drop_file_temp_dir $dir + } + +};# namespace ::tkdnd + +# ---------------------------------------------------------------------------- +# Command tkdnd::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::drag_source { mode path { types {} } { event 1 } + { tagprefix TkDND_Drag } } { + set tags [bindtags $path] + set idx [lsearch $tags ${tagprefix}$event] + switch -- $mode { + register { + if { $idx != -1 } { + ## No need to do anything! + # bindtags $path [lreplace $tags $idx $idx ${tagprefix}$event] + } else { + bindtags $path [linsert $tags 1 ${tagprefix}$event] + } + _drag_source_update_types $path $types + } + unregister { + if { $idx != -1 } { + bindtags $path [lreplace $tags $idx $idx] + } + } + } +};# tkdnd::drag_source + +proc ::tkdnd::_drag_source_update_types { path types } { + set types [platform_specific_types $types] + set old_types [bind $path <>] + foreach type $types { + if {[lsearch $old_types $type] < 0} {lappend old_types $type} + } + bind $path <> $old_types +};# ::tkdnd::_drag_source_update_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::drop_target { mode path { types {} } } { + variable _windowingsystem + set types [platform_specific_types $types] + switch -- $mode { + register { + switch $_windowingsystem { + x11 { + _register_types $path [winfo toplevel $path] $types + } + win32 - + windows { + _RegisterDragDrop $path + bind $path {+ tkdnd::_RevokeDragDrop %W} + } + aqua { + macdnd::registerdragwidget [winfo toplevel $path] $types + } + default { + error "unknown Tk windowing system" + } + } + set old_types [bind $path <>] + set new_types {} + foreach type $types { + if {[lsearch -exact $old_types $type] < 0} {lappend new_types $type} + } + if {[llength $new_types]} { + bind $path <> [concat $old_types $new_types] + } + } + unregister { + switch $_windowingsystem { + x11 { + } + win32 - + windows { + _RevokeDragDrop $path + } + aqua { + error todo + } + default { + error "unknown Tk windowing system" + } + } + bind $path <> {} + } + } +};# tkdnd::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_begin_drag { event button source state X Y x y } { + variable _x0 + variable _y0 + variable _state + + switch -- $event { + press { + set _x0 $X + set _y0 $Y + set _state "press" + } + motion { + if { ![info exists _state] } { + # This is just extra protection. There seem to be + # rare cases where the motion comes before the press. + return + } + if { [string equal $_state "press"] } { + variable _dx + variable _dy + if { abs($_x0-$X) > ${_dx} || abs($_y0-$Y) > ${_dy} } { + set _state "done" + _init_drag $button $source $state $X $Y $x $y + } + } + } + } +};# tkdnd::_begin_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_init_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_init_drag { button source state rootX rootY X Y } { + # Call the <> binding. + set cmd [bind $source <>] + # puts "CMD: $cmd" + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y \ + %S $state %e <> %A \{\} %% % \ + %t [bind $source <>]] $cmd] + set code [catch {uplevel \#0 $cmd} info options] + # puts "CODE: $code ---- $info" + switch -exact -- $code { + 0 {} + 3 - 4 { + # FRINK: nocheck + return + } + default { + return -options $options $info + } + } + + set len [llength $info] + if {$len == 3} { + foreach { actions types _data } $info { break } + set types [platform_specific_types $types] + set data [list] + foreach type $types { + lappend data $_data + } + unset _data + } elseif {$len == 2} { + foreach { actions _data } $info { break } + set data [list]; set types [list] + foreach {t d} $_data { + foreach t [platform_specific_types $t] { + lappend types $t; lappend data $d + } + } + unset _data t d + } else { + if {$len == 1 && [string equal [lindex $actions 0] "refuse_drop"]} { + return + } + error "not enough items in the result of the <>\ + event binding. Either 2 or 3 items are expected. The command + executed was: \"$cmd\"\nResult was: \"$info\"" + } + set action refuse_drop + variable _windowingsystem + # puts "Source: \"$source\"" + # puts "Types: \"[join $types {", "}]\"" + # puts "Actions: \"[join $actions {", "}]\"" + # puts "Button: \"$button\"" + # puts "Data: \"[string range $data 0 100]\"" + switch $_windowingsystem { + x11 { + set action [xdnd::_dodragdrop $source $actions $types $data $button] + } + win32 - + windows { + set action [_DoDragDrop $source $actions $types $data $button] + } + aqua { + set action [macdnd::dodragdrop $source $actions $types $data $button] + } + default { + error "unknown Tk windowing system" + } + } + ## Call _end_drag to notify the widget of the result of the drag + ## operation... + _end_drag $button $source {} $action {} $data {} $state $rootX $rootY $X $Y + } +};# tkdnd::_init_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::_end_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::_end_drag { button source target action type data result + state rootX rootY X Y } { + set rootX 0 + set rootY 0 + # Call the <> binding. + set cmd [bind $source <>] + if {[string length $cmd]} { + set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y %% % \ + %S $state %e <> %A \{$action\}] $cmd] + set info [uplevel \#0 $cmd] + # if { $info != "" } { + # variable _windowingsystem + # foreach { actions types data } $info { break } + # set types [platform_specific_types $types] + # switch $_windowingsystem { + # x11 { + # error "dragging from Tk widgets not yet supported" + # } + # win32 - + # windows { + # set action [_DoDragDrop $source $actions $types $data $button] + # } + # aqua { + # macdnd::dodragdrop $source $actions $types $data + # } + # default { + # error "unknown Tk windowing system" + # } + # } + # ## Call _end_drag to notify the widget of the result of the drag + # ## operation... + # _end_drag $button $source {} $action {} $data {} $state $rootX $rootY + # } + } +};# tkdnd::_end_drag + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_types $types +}; # tkdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_specific_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_specific_type $type +}; # tkdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_type { type } { + variable _platform_namespace + ${_platform_namespace}::platform_independent_type $type +}; # tkdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::bytes_to_string +# ---------------------------------------------------------------------------- +proc ::tkdnd::bytes_to_string { bytes } { + set string {} + foreach byte $bytes { + append string [binary format c $byte] + } + return $string +};# tkdnd::bytes_to_string + +# ---------------------------------------------------------------------------- +# Command tkdnd::urn_unquote +# ---------------------------------------------------------------------------- +proc ::tkdnd::urn_unquote {url} { + set result "" + set start 0 + while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { + foreach {first last} $match break + append result [string range $url $start [expr {$first - 1}]] + append result [format %c 0x[string range $url [incr first] $last]] + set start [incr last] + } + append result [string range $url $start end] + return [encoding convertfrom utf-8 $result] +};# tkdnd::urn_unquote diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd2.9.2.lib b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd2.9.2.lib new file mode 100644 index 0000000000000000000000000000000000000000..c5a956bfdf01319ce0574a1ae86e13454ce22a5f Binary files /dev/null and b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd2.9.2.lib differ diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_compat.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_compat.tcl new file mode 100644 index 0000000000000000000000000000000000000000..efc96f7bb2fe74a9bafd1e79681c275c8ea0f8fc --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_compat.tcl @@ -0,0 +1,160 @@ +# +# tkdnd_compat.tcl -- +# +# This file implements some utility procedures, to support older versions +# of the TkDND package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval compat { + +};# namespace compat + +# ---------------------------------------------------------------------------- +# Command ::dnd +# ---------------------------------------------------------------------------- +proc ::dnd {method window args} { + switch $method { + bindtarget { + switch [llength $args] { + 0 {return [tkdnd::compat::bindtarget0 $window]} + 1 {return [tkdnd::compat::bindtarget1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindtarget2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindtarget3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + 4 {return [tkdnd::compat::bindtarget4 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2] [lindex $args 3]]} + } + } + cleartarget { + return [tkdnd::compat::cleartarget $window] + } + bindsource { + switch [llength $args] { + 0 {return [tkdnd::compat::bindsource0 $window]} + 1 {return [tkdnd::compat::bindsource1 $window [lindex $args 0]]} + 2 {return [tkdnd::compat::bindsource2 $window [lindex $args 0] \ + [lindex $args 1]]} + 3 {return [tkdnd::compat::bindsource3 $window [lindex $args 0] \ + [lindex $args 1] [lindex $args 2]]} + } + } + clearsource { + return [tkdnd::compat::clearsource $window] + } + drag { + return [tkdnd::_init_drag 1 $window "press" 0 0 0 0] + } + } + error "invalid number of arguments!" +};# ::dnd + +# ---------------------------------------------------------------------------- +# Command compat::bindtarget +# ---------------------------------------------------------------------------- +proc compat::bindtarget0 {window} { + return [bind $window <>] +};# compat::bindtarget0 + +proc compat::bindtarget1 {window type} { + return [bindtarget2 $window $type ] +};# compat::bindtarget1 + +proc compat::bindtarget2 {window type event} { + switch $event { + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + {return [bind $window <>]} + } +};# compat::bindtarget2 + +proc compat::bindtarget3 {window type event script} { + set type [normalise_type $type] + ::tkdnd::drop_target register $window [list $type] + switch $event { + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + {return [bind $window <> $script]} + } +};# compat::bindtarget3 + +proc compat::bindtarget4 {window type event script priority} { + return [bindtarget3 $window $type $event $script] +};# compat::bindtarget4 + +proc compat::normalise_type { type } { + switch $type { + text/plain - + {text/plain;charset=UTF-8} - + Text {return DND_Text} + text/uri-list - + Files {return DND_Files} + default {return $type} + } +};# compat::normalise_type + +# ---------------------------------------------------------------------------- +# Command compat::bindsource +# ---------------------------------------------------------------------------- +proc compat::bindsource0 {window} { + return [bind $window <>] +};# compat::bindsource0 + +proc compat::bindsource1 {window type} { + return [bindsource2 $window $type ] +};# compat::bindsource1 + +proc compat::bindsource2 {window type script} { + set type [normalise_type $type] + ::tkdnd::drag_source register $window $type + bind $window <> "list {copy} {%t} \[$script\]" +};# compat::bindsource2 + +proc compat::bindsource3 {window type script priority} { + return [bindsource2 $window $type $script] +};# compat::bindsource3 + +# ---------------------------------------------------------------------------- +# Command compat::cleartarget +# ---------------------------------------------------------------------------- +proc compat::cleartarget {window} { +};# compat::cleartarget + +# ---------------------------------------------------------------------------- +# Command compat::clearsource +# ---------------------------------------------------------------------------- +proc compat::clearsource {window} { +};# compat::clearsource diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_generic.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_generic.tcl new file mode 100644 index 0000000000000000000000000000000000000000..698b464fc68e8a2e0e681f5bac32c4c63338f2c3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_generic.tcl @@ -0,0 +1,520 @@ +# +# tkdnd_generic.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval generic { + variable _types {} + variable _typelist {} + variable _codelist {} + variable _actionlist {} + variable _pressedkeys {} + variable _action {} + variable _common_drag_source_types {} + variable _common_drop_target_types {} + variable _drag_source {} + variable _drop_target {} + + variable _last_mouse_root_x 0 + variable _last_mouse_root_y 0 + + variable _tkdnd2platform + variable _platform2tkdnd + + proc debug {msg} { + puts $msg + };# debug + + proc initialise { } { + };# initialise + + proc initialise_platform_to_tkdnd_types { types } { + variable _platform2tkdnd + variable _tkdnd2platform + set _platform2tkdnd [dict create {*}$types] + set _tkdnd2platform [dict create] + foreach type [dict keys $_platform2tkdnd] { + dict lappend _tkdnd2platform [dict get $_platform2tkdnd $type] $type + } + };# initialise_platform_to_tkdnd_types + + proc initialise_tkdnd_to_platform_types { types } { + variable _tkdnd2platform + set _tkdnd2platform [dict create {*}$types] + };# initialise_tkdnd_to_platform_types + +};# namespace generic + +# ---------------------------------------------------------------------------- +# Command generic::HandleEnter +# ---------------------------------------------------------------------------- +proc generic::HandleEnter { drop_target drag_source typelist codelist + actionlist pressedkeys } { + variable _typelist; set _typelist $typelist + variable _pressedkeys; set _pressedkeys $pressedkeys + variable _action; set _action refuse_drop + variable _common_drag_source_types; set _common_drag_source_types {} + variable _common_drop_target_types; set _common_drop_target_types {} + variable _actionlist + variable _drag_source; set _drag_source $drag_source + variable _drop_target; set _drop_target {} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist + + variable _last_mouse_root_x; set _last_mouse_root_x 0 + variable _last_mouse_root_y; set _last_mouse_root_y 0 + # debug "\n===============================================================" + # debug "generic::HandleEnter: drop_target=$drop_target,\ + # drag_source=$drag_source,\ + # typelist=$typelist" + # debug "generic::HandleEnter: ACTION: default" + return default +};# generic::HandleEnter + +# ---------------------------------------------------------------------------- +# Command generic::HandlePosition +# ---------------------------------------------------------------------------- +proc generic::HandlePosition { drop_target drag_source pressedkeys + rootX rootY { time 0 } } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + # debug "generic::HandlePosition: drop_target=$drop_target,\ + # _drop_target=$_drop_target, rootX=$rootX, rootY=$rootY" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + # debug "generic::HandlePosition: no or empty _drag_source:\ + # return refuse_drop" + return refuse_drop + } + + if {$drag_source ne "" && $drag_source ne $_drag_source} { + debug "generic position event from unexpected source: $_drag_source\ + != $drag_source" + return refuse_drop + } + + set _pressedkeys $pressedkeys + + ## Does the new drop target support any of our new types? + # foreach {common_drag_source_types common_drop_target_types} \ + # [GetWindowCommonTypes $drop_target $_typelist] {break} + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [FindWindowWithCommonTypes $drop_target $_typelist] {break} + set data [GetDroppedData $time] + + # debug "\t($_drop_target) -> ($drop_target)" + if {$drop_target != $_drop_target} { + if {[string length $_drop_target]} { + ## Call the <> event. + # debug "\t<> on $_drop_target" + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + uplevel \#0 $cmd + } + } + set _drop_target $drop_target + set _action refuse_drop + + if {[llength $common_drag_source_types]} { + set _action [lindex $_actionlist 0] + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + ## Drop target supports at least one type. Send a <>. + # puts "<> -> $drop_target" + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + focus $drop_target + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + } + } + } + + set _drop_target {} + if {[llength $common_drag_source_types]} { + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <>. + set cmd [bind $drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + # Return values: copy, move, link, ask, private, refuse_drop, default + # debug "generic::HandlePosition: ACTION: $_action" + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandlePosition + +# ---------------------------------------------------------------------------- +# Command generic::HandleLeave +# ---------------------------------------------------------------------------- +proc generic::HandleLeave { } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + if {![info exists _drop_target]} {set _drop_target {}} + # debug "generic::HandleLeave: _drop_target=$_drop_target" + if {[info exists _drop_target] && [string length $_drop_target]} { + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target \ + %X $_last_mouse_root_x %Y $_last_mouse_root_y \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + foreach var {_types _typelist _actionlist _pressedkeys _action + _common_drag_source_types _common_drop_target_types + _drag_source _drop_target} { + set $var {} + } +};# generic::HandleLeave + +# ---------------------------------------------------------------------------- +# Command generic::HandleDrop +# ---------------------------------------------------------------------------- +proc generic::HandleDrop {drop_target drag_source pressedkeys rootX rootY time } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + set _pressedkeys $pressedkeys + + # puts "generic::HandleDrop: $time" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + return refuse_drop + } + if {![info exists _drop_target] && ![string length $_drop_target]} { + return refuse_drop + } + if {![llength $_common_drag_source_types]} {return refuse_drop} + ## Get the dropped data. + set data [GetDroppedData $time] + ## Try to select the most specific <> event. + foreach type [concat $_common_drag_source_types $_common_drop_target_types] { + set type [platform_independent_type $type] + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action + } + } + set cmd [bind $_drop_target <>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandleDrop + +# ---------------------------------------------------------------------------- +# Command generic::GetWindowCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetWindowCommonTypes { win typelist } { + set types [bind $win <>] + # debug ">> Accepted types: $win $_types" + set common_drag_source_types {} + set common_drop_target_types {} + if {[llength $types]} { + ## Examine the drop target types, to find at least one match with the drag + ## source types... + set supported_types [supported_types $typelist] + foreach type $types { + foreach matched [lsearch -glob -all -inline $supported_types $type] { + ## Drop target supports this type. + lappend common_drag_source_types $matched + lappend common_drop_target_types $type + } + } + } + list $common_drag_source_types $common_drop_target_types +};# generic::GetWindowCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::FindWindowWithCommonTypes +# ---------------------------------------------------------------------------- +proc generic::FindWindowWithCommonTypes { win typelist } { + set toplevel [winfo toplevel $win] + while {![string equal $win $toplevel]} { + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + set win [winfo parent $win] + } + ## We have reached the toplevel, which may be also a target (SF Bug #30) + foreach {common_drag_source_types common_drop_target_types} \ + [GetWindowCommonTypes $win $typelist] {break} + if {[llength $common_drag_source_types]} { + return [list $win $common_drag_source_types $common_drop_target_types] + } + return { {} {} {} } +};# generic::FindWindowWithCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDroppedData +# ---------------------------------------------------------------------------- +proc generic::GetDroppedData { time } { + variable _dropped_data + return $_dropped_data +};# generic::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::SetDroppedData +# ---------------------------------------------------------------------------- +proc generic::SetDroppedData { data } { + variable _dropped_data + set _dropped_data $data +};# generic::SetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSource +# ---------------------------------------------------------------------------- +proc generic::GetDragSource { } { + variable _drag_source + return $_drag_source +};# generic::GetDragSource + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTarget +# ---------------------------------------------------------------------------- +proc generic::GetDropTarget { } { + variable _drop_target + return $_drop_target +};# generic::GetDropTarget + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDragSourceCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTargetCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDropTargetCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDropTargetCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_types +# ---------------------------------------------------------------------------- +proc generic::platform_specific_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_specific_type $type]] + } + return $new_types +}; # generic::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_type +# ---------------------------------------------------------------------------- +proc generic::platform_specific_type { type } { + variable _tkdnd2platform + if {[dict exists $_tkdnd2platform $type]} { + return [dict get $_tkdnd2platform $type] + } + list $type +}; # generic::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_independent_type $type]] + } + return $new_types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_type +# ---------------------------------------------------------------------------- +proc generic::platform_independent_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return [dict get $_platform2tkdnd $type] + } + return $type +}; # generic::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command generic::supported_types +# ---------------------------------------------------------------------------- +proc generic::supported_types { types } { + set new_types {} + foreach type $types { + if {[supported_type $type]} {lappend new_types $type} + } + return $new_types +}; # generic::supported_types + +# ---------------------------------------------------------------------------- +# Command generic::supported_type +# ---------------------------------------------------------------------------- +proc generic::supported_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return 1 + } + return 0 +}; # generic::supported_type diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_macosx.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_macosx.tcl new file mode 100644 index 0000000000000000000000000000000000000000..307f6da2e94286d01dc9e068fffebe46de3c43f3 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_macosx.tcl @@ -0,0 +1,144 @@ +# +# tkdnd_macosx.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. + +# This software is copyrighted by: +# Georgios Petasis, Athens, Greece. +# e-mail: petasisg@yahoo.gr, petasis@iit.demokritos.gr +# +# Mac portions (c) 2009 Kevin Walzer/WordTech Communications LLC, +# kw@codebykevin.com +# +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +#basic API for Mac Drag and Drop + +#two data types supported: strings and file paths + +#two commands at C level: ::tkdnd::macdnd::registerdragwidget, ::tkdnd::macdnd::unregisterdragwidget + +#data retrieval mechanism: text or file paths are copied from drag clipboard to system clipboard and retrieved via [clipboard get]; array of file paths is converted to single tab-separated string, can be split into Tcl list + +if {[tk windowingsystem] eq "aqua" && "AppKit" ni [winfo server .]} { + error {TkAqua Cocoa required} +} + +namespace eval macdnd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + NSPasteboardTypeString DND_Text \ + NSFilenamesPboardType DND_Files \ + NSPasteboardTypeHTML DND_HTML \ + ] + };# initialise + +};# namespace macdnd + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleEnter +# ---------------------------------------------------------------------------- +proc macdnd::HandleEnter { path drag_source typelist { data {} } } { + variable _pressedkeys + variable _actionlist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# macdnd::HandleEnter + +# ---------------------------------------------------------------------------- +# Command macdnd::HandlePosition +# ---------------------------------------------------------------------------- +proc macdnd::HandlePosition { drop_target rootX rootY {drag_source {}} } { + variable _pressedkeys + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# macdnd::HandlePosition + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleLeave +# ---------------------------------------------------------------------------- +proc macdnd::HandleLeave { args } { + ::tkdnd::generic::HandleLeave +};# macdnd::HandleLeave + +# ---------------------------------------------------------------------------- +# Command macdnd::HandleDrop +# ---------------------------------------------------------------------------- +proc macdnd::HandleDrop { drop_target data args } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y 0 +};# macdnd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command macdnd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc macdnd::GetDragSourceCommonTypes { } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# macdnd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # macdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # macdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command macdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc macdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # macdnd::platform_independent_type diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_unix.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_unix.tcl new file mode 100644 index 0000000000000000000000000000000000000000..56d17c4db718274df4b3b7a14f0d8e055a1002b6 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_unix.tcl @@ -0,0 +1,810 @@ +# +# tkdnd_unix.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval xdnd { + variable _dragging 0 + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + text/plain\;charset=utf-8 DND_Text \ + UTF8_STRING DND_Text \ + text/plain DND_Text \ + STRING DND_Text \ + TEXT DND_Text \ + COMPOUND_TEXT DND_Text \ + text/uri-list DND_Files \ + text/html\;charset=utf-8 DND_HTML \ + text/html DND_HTML \ + application/x-color DND_Color \ + ] + };# initialise + +};# namespace xdnd + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndEnter { path drag_source typelist time { data {} } } { + variable _pressedkeys + variable _actionlist + variable _typelist + set _pressedkeys 1 + set _actionlist { copy move link ask private } + set _typelist $typelist + # puts "xdnd::HandleXdndEnter: $time" + ::tkdnd::generic::SetDroppedData $data + ::tkdnd::generic::HandleEnter $path $drag_source $typelist $typelist \ + $_actionlist $_pressedkeys +};# xdnd::HandleXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndPosition { drop_target rootX rootY time {drag_source {}} } { + variable _pressedkeys + variable _typelist + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + # puts "xdnd::HandleXdndPosition: $time" + ## Get the dropped data... + catch { + ::tkdnd::generic::SetDroppedData [GetPositionData $drop_target $_typelist $time] + } + ::tkdnd::generic::HandlePosition $drop_target $drag_source \ + $_pressedkeys $rootX $rootY +};# xdnd::HandleXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::HandleXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndLeave { } { + ::tkdnd::generic::HandleLeave +};# xdnd::HandleXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::HandleXdndDrop { time } { + variable _pressedkeys + variable _last_mouse_root_x + variable _last_mouse_root_y + ## Get the dropped data... + ::tkdnd::generic::SetDroppedData [GetDroppedData \ + [::tkdnd::generic::GetDragSource] [::tkdnd::generic::GetDropTarget] \ + [::tkdnd::generic::GetDragSourceCommonTypes] $time] + ::tkdnd::generic::HandleDrop {} {} $_pressedkeys \ + $_last_mouse_root_x $_last_mouse_root_y $time +};# xdnd::HandleXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::GetPositionData +# ---------------------------------------------------------------------------- +proc xdnd::GetPositionData { drop_target typelist time } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + GetDroppedData [::tkdnd::generic::GetDragSource] $drop_target \ + $common_drag_source_types $time +};# xdnd::GetPositionData + +# ---------------------------------------------------------------------------- +# Command xdnd::GetDroppedData +# ---------------------------------------------------------------------------- +proc xdnd::GetDroppedData { _drag_source _drop_target _common_drag_source_types time } { + if {![llength $_common_drag_source_types]} { + error "no common data types between the drag source and drop target widgets" + } + ## Is drag source in this application? + if {[catch {winfo pathname -displayof $_drop_target $_drag_source} p]} { + set _use_tk_selection 0 + } else { + set _use_tk_selection 1 + } + foreach type $_common_drag_source_types { + # puts "TYPE: $type ($_drop_target)" + # _get_selection $_drop_target $time $type + if {$_use_tk_selection} { + if {![catch { + selection get -displayof $_drop_target -selection XdndSelection \ + -type $type + } result options]} { + return [normalise_data $type $result] + } + } else { + # puts "_selection_get -displayof $_drop_target -selection XdndSelection \ + # -type $type -time $time" + #after 100 [list focus -force $_drop_target] + #after 50 [list raise [winfo toplevel $_drop_target]] + if {![catch { + _selection_get -displayof $_drop_target -selection XdndSelection \ + -type $type -time $time + } result options]} { + return [normalise_data $type $result] + } + } + } + return -options $options $result +};# xdnd::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_types +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # xdnd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_specific_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # xdnd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command xdnd::platform_independent_type +# ---------------------------------------------------------------------------- +proc xdnd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # xdnd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command xdnd::_normalise_data +# ---------------------------------------------------------------------------- +proc xdnd::normalise_data { type data } { + # Tk knows how to interpret the following types: + # STRING, TEXT, COMPOUND_TEXT + # UTF8_STRING + # Else, it returns a list of 8 or 32 bit numbers... + switch -glob $type { + STRING - UTF8_STRING - TEXT - COMPOUND_TEXT {return $data} + text/html { + if {[catch { + encoding convertfrom unicode $data + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/html\;charset=utf-8 - + text/plain\;charset=utf-8 - + text/plain { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + return [string map {\r\n \n} $string] + } + text/uri-list* { + if {[catch { + encoding convertfrom utf-8 [tkdnd::bytes_to_string $data] + } string]} { + set string $data + } + ## Get rid of \r\n + set string [string trim [string map {\r\n \n} $string]] + set files {} + foreach quoted_file [split $string] { + set file [tkdnd::urn_unquote $quoted_file] + switch -glob $file { + \#* {} + file://* {lappend files [string range $file 7 end]} + ftp://* - + https://* - + http://* {lappend files $quoted_file} + default {lappend files $file} + } + } + return $files + } + application/x-color { + return $data + } + text/x-moz-url - + application/q-iconlist - + default {return $data} + } +}; # xdnd::normalise_data + +############################################################################# +## +## XDND drag implementation +## +############################################################################# + +# ---------------------------------------------------------------------------- +# Command xdnd::_selection_ownership_lost +# ---------------------------------------------------------------------------- +proc xdnd::_selection_ownership_lost {} { + variable _dragging + set _dragging 0 +};# _selection_ownership_lost + +# ---------------------------------------------------------------------------- +# Command xdnd::_dodragdrop +# ---------------------------------------------------------------------------- +proc xdnd::_dodragdrop { source actions types data button } { + variable _dragging + + # puts "xdnd::_dodragdrop: source: $source, actions: $actions, types: $types,\ + # data: \"$data\", button: $button" + if {$_dragging} { + ## We are in the middle of another drag operation... + error "another drag operation in progress" + } + + variable _dodragdrop_drag_source $source + variable _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_proxy 0 + variable _dodragdrop_actions $actions + variable _dodragdrop_action_descriptions $actions + variable _dodragdrop_actions_len [llength $actions] + variable _dodragdrop_types $types + variable _dodragdrop_types_len [llength $types] + variable _dodragdrop_data $data + variable _dodragdrop_transfer_data {} + variable _dodragdrop_button $button + variable _dodragdrop_time 0 + variable _dodragdrop_default_action refuse_drop + variable _dodragdrop_waiting_status 0 + variable _dodragdrop_drop_target_accepts_drop 0 + variable _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_current_cursor $_dodragdrop_default_action + variable _dodragdrop_drop_occured 0 + variable _dodragdrop_selection_requestor 0 + + ## + ## If we have more than 3 types, the property XdndTypeList must be set on + ## the drag source widget... + ## + if {$_dodragdrop_types_len > 3} { + _announce_type_list $_dodragdrop_drag_source $_dodragdrop_types + } + + ## + ## Announce the actions & their descriptions on the XdndActionList & + ## XdndActionDescription properties... + ## + _announce_action_list $_dodragdrop_drag_source $_dodragdrop_actions \ + $_dodragdrop_action_descriptions + + ## + ## Arrange selection handlers for our drag source, and all the supported types + ## + registerSelectionHandler $source $types + + ## + ## Step 1: When a drag begins, the source takes ownership of XdndSelection. + ## + selection own -command ::tkdnd::xdnd::_selection_ownership_lost \ + -selection XdndSelection $source + set _dragging 1 + + ## Grab the mouse pointer... + _grab_pointer $source $_dodragdrop_default_action + + ## Register our generic event handler... + # The generic event callback will report events by modifying variable + # ::xdnd::_dodragdrop_event: a dict with event information will be set as + # the value of the variable... + _register_generic_event_handler + + ## Set a timeout for debugging purposes... + # after 60000 {set ::tkdnd::xdnd::_dragging 0} + + tkwait variable ::tkdnd::xdnd::_dragging + _SendXdndLeave + + set _dragging 0 + _ungrab_pointer $source + _unregister_generic_event_handler + catch {selection clear -selection XdndSelection} + unregisterSelectionHandler $source $types + return $_dodragdrop_drop_target_accepts_action +};# xdnd::_dodragdrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_process_drag_events +# ---------------------------------------------------------------------------- +proc xdnd::_process_drag_events {event} { + # The return value from proc is normally 0. A non-zero return value indicates + # that the event is not to be handled further; that is, proc has done all + # processing that is to be allowed for the event + variable _dragging + if {!$_dragging} {return 0} + # puts $event + + variable _dodragdrop_time + set time [dict get $event time] + set type [dict get $event type] + if {$time < $_dodragdrop_time && ![string equal $type SelectionRequest]} { + return 0 + } + set _dodragdrop_time $time + + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_default_action + switch $type { + MotionNotify { + set rootx [dict get $event x_root] + set rooty [dict get $event y_root] + set window [_find_drop_target_window $_dodragdrop_drag_source \ + $rootx $rooty] + if {[string length $window]} { + ## Examine the modifiers to suggest an action... + set _dodragdrop_default_action [_default_action $event] + ## Is it a Tk widget? + # set path [winfo containing $rootx $rooty] + # puts "Window under mouse: $window ($path)" + if {$_dodragdrop_drop_target != $window} { + ## Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + ## Is there a proxy? If not, _find_drop_target_proxy returns the + ## target window, so we always get a valid "proxy". + set proxy [_find_drop_target_proxy $_dodragdrop_drag_source $window] + ## Send XdndEnter to $window + _SendXdndEnter $window $proxy + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } else { + ## Send XdndPosition to $_dodragdrop_drop_target + _SendXdndPosition $rootx $rooty $_dodragdrop_default_action + } + } else { + ## No window under the mouse. Send XdndLeave to $_dodragdrop_drop_target + _SendXdndLeave + } + } + ButtonPress { + } + ButtonRelease { + variable _dodragdrop_button + set button [dict get $event button] + if {$button == $_dodragdrop_button} { + ## The button that initiated the drag was released. Trigger drop... + _SendXdndDrop + } + return 1 + } + KeyPress { + } + KeyRelease { + set keysym [dict get $event keysym] + switch $keysym { + Escape { + ## The user has pressed escape. Abort... + if {$_dragging} {set _dragging 0} + } + } + } + SelectionRequest { + variable _dodragdrop_selection_requestor + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + set _dodragdrop_selection_requestor [dict get $event requestor] + set _dodragdrop_selection_property [dict get $event property] + set _dodragdrop_selection_selection [dict get $event selection] + set _dodragdrop_selection_target [dict get $event target] + set _dodragdrop_selection_time $time + return 0 + } + default { + return 0 + } + } + return 0 +};# _process_drag_events + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndEnter +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndEnter {window proxy} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_types + variable _dodragdrop_waiting_status + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_target > 0} _SendXdndLeave + if {$_dodragdrop_drop_occured} return + set _dodragdrop_drop_target $window + set _dodragdrop_drop_target_proxy $proxy + set _dodragdrop_waiting_status 0 + if {$_dodragdrop_drop_target < 1} return + # puts "XdndEnter: $_dodragdrop_drop_target $_dodragdrop_drop_target_proxy" + _send_XdndEnter $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $_dodragdrop_types +};# xdnd::_SendXdndEnter + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndPosition +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndPosition {rootx rooty action} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_waiting_status + ## Arrange a new XdndPosition, to be send periodically... + variable _dodragdrop_xdnd_position_heartbeat + catch {after cancel $_dodragdrop_xdnd_position_heartbeat} + set _dodragdrop_xdnd_position_heartbeat [after 200 \ + [list ::tkdnd::xdnd::_SendXdndPosition $rootx $rooty $action]] + if {$_dodragdrop_waiting_status} {return} + # puts "XdndPosition: $_dodragdrop_drop_target $rootx $rooty $action" + _send_XdndPosition $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy $rootx $rooty $action + set _dodragdrop_waiting_status 1 +};# xdnd::_SendXdndPosition + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndStatus +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndStatus {event} { + variable _dodragdrop_drop_target + variable _dodragdrop_waiting_status + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_waiting_status 0 + foreach key {target accept want_position action x y w h} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor + # puts "XdndStatus: $event" +};# xdnd::_HandleXdndStatus + +# ---------------------------------------------------------------------------- +# Command xdnd::_HandleXdndFinished +# ---------------------------------------------------------------------------- +proc xdnd::_HandleXdndFinished {event} { + variable _dodragdrop_xdnd_finished_event_after_id + catch {after cancel $_dodragdrop_xdnd_finished_event_after_id} + set _dodragdrop_xdnd_finished_event_after_id {} + variable _dodragdrop_drop_target + set _dodragdrop_drop_target 0 + variable _dragging + if {$_dragging} {set _dragging 0} + + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + if {[dict size $event]} { + foreach key {target accept action} { + set $key [dict get $event $key] + } + set _dodragdrop_drop_target_accepts_drop $accept + set _dodragdrop_drop_target_accepts_action $action + } else { + set _dodragdrop_drop_target_accepts_drop 0 + } + if {!$_dodragdrop_drop_target_accepts_drop} { + set _dodragdrop_drop_target_accepts_action refuse_drop + } + # puts "XdndFinished: $event" +};# xdnd::_HandleXdndFinished + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndLeave +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndLeave {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} return + variable _dodragdrop_drop_target_proxy + # puts "XdndLeave: $_dodragdrop_drop_target" + _send_XdndLeave $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy + set _dodragdrop_drop_target 0 + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + set _dodragdrop_drop_target_accepts_drop 0 + set _dodragdrop_drop_target_accepts_action refuse_drop + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} return + _update_cursor +};# xdnd::_SendXdndLeave + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendXdndDrop +# ---------------------------------------------------------------------------- +proc xdnd::_SendXdndDrop {} { + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target + if {$_dodragdrop_drop_target < 1} { + ## The mouse has been released over a widget that does not accept drops. + _HandleXdndFinished {} + return + } + variable _dodragdrop_drop_occured + if {$_dodragdrop_drop_occured} {return} + variable _dodragdrop_drop_target_proxy + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + set _dodragdrop_drop_occured 1 + _update_cursor clock + + if {!$_dodragdrop_drop_target_accepts_drop} { + _SendXdndLeave + _HandleXdndFinished {} + return + } + # puts "XdndDrop: $_dodragdrop_drop_target" + variable _dodragdrop_drop_timestamp + set _dodragdrop_drop_timestamp [_send_XdndDrop \ + $_dodragdrop_drag_source $_dodragdrop_drop_target \ + $_dodragdrop_drop_target_proxy] + set _dodragdrop_drop_target 0 + # puts "XdndDrop: $_dodragdrop_drop_target" + ## Arrange a timeout for receiving XdndFinished... + variable _dodragdrop_xdnd_finished_event_after_id + set _dodragdrop_xdnd_finished_event_after_id \ + [after 10000 [list ::tkdnd::xdnd::_HandleXdndFinished {}]] +};# xdnd::_SendXdndDrop + +# ---------------------------------------------------------------------------- +# Command xdnd::_update_cursor +# ---------------------------------------------------------------------------- +proc xdnd::_update_cursor { {cursor {}}} { + # puts "_update_cursor $cursor" + variable _dodragdrop_current_cursor + variable _dodragdrop_drag_source + variable _dodragdrop_drop_target_accepts_drop + variable _dodragdrop_drop_target_accepts_action + + if {![string length $cursor]} { + set cursor refuse_drop + if {$_dodragdrop_drop_target_accepts_drop} { + set cursor $_dodragdrop_drop_target_accepts_action + } + } + if {![string equal $cursor $_dodragdrop_current_cursor]} { + _set_pointer_cursor $_dodragdrop_drag_source $cursor + set _dodragdrop_current_cursor $cursor + } +};# xdnd::_update_cursor + +# ---------------------------------------------------------------------------- +# Command xdnd::_default_action +# ---------------------------------------------------------------------------- +proc xdnd::_default_action {event} { + variable _dodragdrop_actions + variable _dodragdrop_actions_len + if {$_dodragdrop_actions_len == 1} {return [lindex $_dodragdrop_actions 0]} + + set alt [dict get $event Alt] + set shift [dict get $event Shift] + set control [dict get $event Control] + + if {$shift && $control && [lsearch $_dodragdrop_actions link] != -1} { + return link + } elseif {$control && [lsearch $_dodragdrop_actions copy] != -1} { + return copy + } elseif {$shift && [lsearch $_dodragdrop_actions move] != -1} { + return move + } elseif {$alt && [lsearch $_dodragdrop_actions link] != -1} { + return link + } + return default +};# xdnd::_default_action + +# ---------------------------------------------------------------------------- +# Command xdnd::getFormatForType +# ---------------------------------------------------------------------------- +proc xdnd::getFormatForType {type} { + switch -glob [string tolower $type] { + text/plain\;charset=utf-8 - + text/html\;charset=utf-8 - + utf8_string {set format UTF8_STRING} + text/html - + text/plain - + string - + text - + compound_text {set format STRING} + text/uri-list* {set format UTF8_STRING} + application/x-color {set format $type} + default {set format $type} + } + return $format +};# xdnd::getFormatForType + +# ---------------------------------------------------------------------------- +# Command xdnd::registerSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::registerSelectionHandler {source types} { + foreach type $types { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source [list ::tkdnd::xdnd::_SendData $type] + } +};# xdnd::registerSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::unregisterSelectionHandler +# ---------------------------------------------------------------------------- +proc xdnd::unregisterSelectionHandler {source types} { + foreach type $types { + catch { + selection handle -selection XdndSelection \ + -type $type \ + -format [getFormatForType $type] \ + $source {} + } + } +};# xdnd::unregisterSelectionHandler + +# ---------------------------------------------------------------------------- +# Command xdnd::_convert_to_unsigned +# ---------------------------------------------------------------------------- +proc xdnd::_convert_to_unsigned {data format} { + switch $format { + 8 { set mask 0xff } + 16 { set mask 0xffff } + 32 { set mask 0xffffff } + default {error "unsupported format $format"} + } + ## Convert signed integer into unsigned... + set d [list] + foreach num $data { + lappend d [expr { $num & $mask }] + } + return $d +};# xdnd::_convert_to_unsigned + +# ---------------------------------------------------------------------------- +# Command xdnd::_SendData +# ---------------------------------------------------------------------------- +proc xdnd::_SendData {type offset bytes args} { + variable _dodragdrop_drag_source + variable _dodragdrop_types + variable _dodragdrop_data + variable _dodragdrop_transfer_data + + ## The variable _dodragdrop_data contains a list of data, one for each + ## type in the _dodragdrop_types variable. We have to search types, and find + ## the corresponding entry in the _dodragdrop_data list. + set index [lsearch $_dodragdrop_types $type] + if {$index < 0} { + error "unable to locate data suitable for type \"$type\"" + } + set typed_data [lindex $_dodragdrop_data $index] + set format 8 + if {$offset == 0} { + ## Prepare the data to be transferred... + switch -glob $type { + text/plain* - UTF8_STRING - STRING - TEXT - COMPOUND_TEXT { + binary scan [encoding convertto utf-8 $typed_data] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + text/uri-list* { + set files [list] + foreach file $typed_data { + switch -glob $file { + *://* {lappend files $file} + default {lappend files file://$file} + } + } + binary scan [encoding convertto utf-8 "[join $files \r\n]\r\n"] \ + c* _dodragdrop_transfer_data + set _dodragdrop_transfer_data \ + [_convert_to_unsigned $_dodragdrop_transfer_data $format] + } + application/x-color { + set format 16 + ## Try to understand the provided data: we accept a standard Tk colour, + ## or a list of 3 values (red green blue) or a list of 4 values + ## (red green blue opacity). + switch [llength $typed_data] { + 1 { set color [winfo rgb $_dodragdrop_drag_source $typed_data] + lappend color 65535 } + 3 { set color $typed_data; lappend color 65535 } + 4 { set color $typed_data } + default {error "unknown color data: \"$typed_data\""} + } + ## Convert the 4 elements into 16 bit values... + set _dodragdrop_transfer_data [list] + foreach c $color { + lappend _dodragdrop_transfer_data [format 0x%04X $c] + } + } + default { + set format 32 + binary scan $typed_data c* _dodragdrop_transfer_data + } + } + } + + ## + ## Data has been split into bytes. Count the bytes requested, and return them + ## + set data [lrange $_dodragdrop_transfer_data $offset [expr {$offset+$bytes-1}]] + switch $format { + 8 { + set data [encoding convertfrom utf-8 [binary format c* $data]] + } + 16 { + variable _dodragdrop_selection_requestor + if {$_dodragdrop_selection_requestor} { + ## Tk selection cannot process this format (only 8 & 32 supported). + ## Call our XChangeProperty... + set numItems [llength $data] + variable _dodragdrop_selection_property + variable _dodragdrop_selection_selection + variable _dodragdrop_selection_target + variable _dodragdrop_selection_time + XChangeProperty $_dodragdrop_drag_source \ + $_dodragdrop_selection_requestor \ + $_dodragdrop_selection_property \ + $_dodragdrop_selection_target \ + $format \ + $_dodragdrop_selection_time \ + $data $numItems + return -code break + } + } + 32 { + } + default { + error "unsupported format $format" + } + } + # puts "SendData: $type $offset $bytes $args ($typed_data)" + # puts " $data" + return $data +};# xdnd::_SendData diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_utils.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_utils.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ee961ddb1ca29b383496111eadc2ccdce7776b08 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_utils.tcl @@ -0,0 +1,252 @@ +# +# tkdnd_utils.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +package require tkdnd +namespace eval ::tkdnd { + namespace eval utils { + };# namespace ::tkdnd::utils + namespace eval text { + variable _drag_tag tkdnd::drag::selection::tag + variable _state {} + variable _drag_source_widget {} + variable _drop_target_widget {} + variable _now_dragging 0 + };# namespace ::tkdnd::text +};# namespace ::tkdnd + +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag clear 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag motion 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_TextAutoScan %W %x %y} +bind TkDND_Drag_Text1 {tkdnd::text::_begin_drag reset 1 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag clear 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag motion 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text2 {tkdnd::text::_begin_drag reset 2 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag clear 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag motion 3 %W %s %X %Y %x %y} +bind TkDND_Drag_Text3 {tkdnd::text::_begin_drag reset 3 %W %s %X %Y %x %y} + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drag_source +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drag_source { mode path { types DND_Text } { event 1 } { tagprefix TkDND_Drag_Text } { tag sel } } { + switch -exact -- $mode { + register { + $path tag bind $tag \ + "tkdnd::text::_begin_drag press ${event} %W %s %X %Y %x %y" + ## Set a binding to the widget, to put selection as data... + bind $path <> "::tkdnd::text::DragInitCmd $path {%t} $tag" + ## Set a binding to the widget, to remove selection if action is move... + bind $path <> "::tkdnd::text::DragEndCmd $path %A $tag" + } + unregister { + $path tag bind $tag {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drag_source $mode $path $types $event $tagprefix +};# ::tkdnd::text::drag_source + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::drop_target +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::drop_target { mode path { types DND_Text } } { + switch -exact -- $mode { + register { + bind $path <> "::tkdnd::text::DropPosition $path %X %Y %A %a %m" + bind $path <> "::tkdnd::text::Drop $path %D %X %Y %A %a %m" + } + unregister { + bind $path <> {} + bind $path <> {} + bind $path <> {} + bind $path <> {} + } + } + ::tkdnd::drop_target $mode $path $types +};# ::tkdnd::text::drop_target + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragInitCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragInitCmd { path { types DND_Text } { tag sel } { actions { copy move } } } { + ## Save the selection indices... + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget $path + set _drop_target_widget {} + _save_selection $path $tag + list $actions $types [$path get $tag.first $tag.last] +};# ::tkdnd::text::DragInitCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DragEndCmd +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DragEndCmd { path action { tag sel } } { + variable _drag_source_widget + variable _drop_target_widget + set _drag_source_widget {} + set _drop_target_widget {} + _restore_selection $path $tag + switch -exact -- $action { + move { + ## Delete the original selected text... + variable _selection_first + variable _selection_last + $path delete $_selection_first $_selection_last + } + } +};# ::tkdnd::text::DragEndCmd + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::DropPosition +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::DropPosition { path X Y action actions keys} { + variable _drag_source_widget + variable _drop_target_widget + set _drop_target_widget $path + ## This check is primitive, a more accurate one is needed! + if {$path eq $_drag_source_widget} { + ## This is a drag within the same widget! Set action to move... + if {"move" in $actions} {set action move} + } + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y; update + return $action +};# ::tkdnd::text::DropPosition + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::Drop +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::Drop { path data X Y action actions keys } { + incr X -[winfo rootx $path] + incr Y -[winfo rooty $path] + $path mark set insert @$X,$Y + $path insert [$path index insert] $data + return $action +};# ::tkdnd::text::Drop + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_save_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_save_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + variable _selection_tag $tag + set _selection_first [$path index $tag.first] + set _selection_last [$path index $tag.last] + $path tag add $_drag_tag $_selection_first $_selection_last + $path tag configure $_drag_tag \ + -background [$path tag cget $tag -background] \ + -foreground [$path tag cget $tag -foreground] +};# tkdnd::text::_save_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_restore_selection +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_restore_selection { path tag} { + variable _drag_tag + variable _selection_first + variable _selection_last + $path tag delete $_drag_tag + $path tag remove $tag 0.0 end + #$path tag add $tag $_selection_first $_selection_last +};# tkdnd::text::_restore_selection + +# ---------------------------------------------------------------------------- +# Command tkdnd::text::_begin_drag +# ---------------------------------------------------------------------------- +proc ::tkdnd::text::_begin_drag { event button source state X Y x y } { + variable _drop_target_widget + variable _state + # puts "::tkdnd::text::_begin_drag $event $button $source $state $X $Y $x $y" + + switch -exact -- $event { + clear { + switch -exact -- $_state { + press { + ## Do not execute other bindings, as they will erase selection... + return -code break + } + } + set _state clear + } + motion { + variable _now_dragging + if {$_now_dragging} {return -code break} + if { [string equal $_state "press"] } { + variable _x0; variable _y0 + if { abs($_x0-$X) > ${::tkdnd::_dx} || abs($_y0-$Y) > ${::tkdnd::_dy} } { + set _state "done" + set _drop_target_widget {} + set _now_dragging 1 + set code [catch { + ::tkdnd::_init_drag $button $source $state $X $Y $x $y + } info options] + set _drop_target_widget {} + set _now_dragging 0 + if {$code != 0} { + ## Something strange occurred... + return -options $options $info + } + } + return -code break + } + set _state clear + } + press { + variable _x0; variable _y0 + set _x0 $X + set _y0 $Y + set _state "press" + } + reset { + set _state {} + } + } + if {$source eq $_drop_target_widget} {return -code break} + return -code continue +};# tkdnd::text::_begin_drag + +proc tkdnd::text::_TextAutoScan {w x y} { + variable _now_dragging + if {$_now_dragging} {return -code break} + return -code continue +};# tkdnd::text::_TextAutoScan diff --git a/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_windows.tcl b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_windows.tcl new file mode 100644 index 0000000000000000000000000000000000000000..a1d01f3a2c438eaf3f676437d4d4ba89b3ba64f0 --- /dev/null +++ b/gui_data/tkinterdnd2/tkdnd/win64/tkdnd_windows.tcl @@ -0,0 +1,167 @@ +# +# tkdnd_windows.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval olednd { + + proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + CF_UNICODETEXT DND_Text \ + CF_TEXT DND_Text \ + CF_HDROP DND_Files \ + UniformResourceLocator DND_URL \ + CF_HTML DND_HTML \ + {HTML Format} DND_HTML \ + CF_RTF DND_RTF \ + CF_RTFTEXT DND_RTF \ + {Rich Text Format} DND_RTF \ + ] + # FileGroupDescriptorW DND_Files \ + # FileGroupDescriptor DND_Files \ + + ## Mapping from TkDND types to platform types... + ::tkdnd::generic::initialise_tkdnd_to_platform_types [list \ + DND_Text {CF_UNICODETEXT CF_TEXT} \ + DND_Files {CF_HDROP} \ + DND_URL {UniformResourceLocator UniformResourceLocatorW} \ + DND_HTML {CF_HTML {HTML Format}} \ + DND_RTF {CF_RTF CF_RTFTEXT {Rich Text Format}} \ + ] + };# initialise + +};# namespace olednd + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragEnter +# ---------------------------------------------------------------------------- +proc olednd::HandleDragEnter { drop_target typelist actionlist pressedkeys + rootX rootY codelist { data {} } } { + ::tkdnd::generic::SetDroppedData $data + focus $drop_target + ::tkdnd::generic::HandleEnter $drop_target 0 $typelist \ + $codelist $actionlist $pressedkeys + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragEnter + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragOver +# ---------------------------------------------------------------------------- +proc olednd::HandleDragOver { drop_target pressedkeys rootX rootY } { + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDragOver + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDragLeave +# ---------------------------------------------------------------------------- +proc olednd::HandleDragLeave { drop_target } { + ::tkdnd::generic::HandleLeave + if {$::tkdnd::_auto_update} {update idletasks} +};# olednd::HandleDragLeave + +# ---------------------------------------------------------------------------- +# Command olednd::HandleDrop +# ---------------------------------------------------------------------------- +proc olednd::HandleDrop { drop_target pressedkeys rootX rootY type data } { + ::tkdnd::generic::SetDroppedData [normalise_data $type $data] + set action [::tkdnd::generic::HandleDrop $drop_target {} \ + $pressedkeys $rootX $rootY 0] + if {$::tkdnd::_auto_update} {update idletasks} + return $action +};# olednd::HandleDrop + +# ---------------------------------------------------------------------------- +# Command olednd::GetDataType +# ---------------------------------------------------------------------------- +proc olednd::GetDataType { drop_target typelist } { + foreach {drop_target common_drag_source_types common_drop_target_types} \ + [::tkdnd::generic::FindWindowWithCommonTypes $drop_target $typelist] {break} + lindex $common_drag_source_types 0 +};# olednd::GetDataType + +# ---------------------------------------------------------------------------- +# Command olednd::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc olednd::GetDragSourceCommonTypes { drop_target } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# olednd::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_types +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # olednd::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_specific_type +# ---------------------------------------------------------------------------- +proc olednd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # olednd::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command olednd::platform_independent_type +# ---------------------------------------------------------------------------- +proc olednd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # olednd::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command olednd::normalise_data +# ---------------------------------------------------------------------------- +proc olednd::normalise_data { type data } { + switch [lindex [::tkdnd::generic::platform_independent_type $type] 0] { + DND_Text {return $data} + DND_Files {return $data} + DND_HTML {return [encoding convertfrom utf-8 $data]} + default {return $data} + } +}; # olednd::normalise_data