void editcmd_dialog_select_definition_show (WEdit * edit, char *match_expr, int max_len, int word_len, etags_hash_t * def_hash, int num_lines) { int start_x, start_y, offset, i; char *curr = NULL; etags_hash_t *curr_def = NULL; WDialog *def_dlg; WListbox *def_list; int def_dlg_h; /* dialog height */ int def_dlg_w; /* dialog width */ (void) word_len; /* calculate the dialog metrics */ def_dlg_h = num_lines + 2; def_dlg_w = max_len + 4; start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2) + EDIT_TEXT_HORIZONTAL_OFFSET + (edit->fullscreen ? 0 : 1) + option_line_state_width; start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + (edit->fullscreen ? 0 : 1) + 1; if (start_x < 0) start_x = 0; if (def_dlg_w > COLS) def_dlg_w = COLS; if (def_dlg_h > LINES - 2) def_dlg_h = LINES - 2; offset = start_x + def_dlg_w - COLS; if (offset > 0) start_x -= offset; offset = start_y + def_dlg_h - LINES; if (offset > 0) start_y -= (offset + 1); /* create the dialog */ def_dlg = dlg_create (TRUE, start_y, start_x, def_dlg_h, def_dlg_w, WPOS_KEEP_DEFAULT, TRUE, dialog_colors, NULL, NULL, "[Definitions]", match_expr); /* create the listbox */ def_list = listbox_new (1, 1, def_dlg_h - 2, def_dlg_w - 2, FALSE, NULL); /* add the dialog */ add_widget (def_dlg, def_list); /* fill the listbox with the completions */ for (i = 0; i < num_lines; i++) { char *label_def; label_def = g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename, def_hash[i].line); listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i], FALSE); g_free (label_def); } /* pop up the dialog and apply the chosen completion */ if (dlg_run (def_dlg) == B_ENTER) { char *tmp_curr_def = (char *) curr_def; int do_moveto = 0; listbox_get_current (def_list, &curr, (void **) &tmp_curr_def); curr_def = (etags_hash_t *) tmp_curr_def; if (edit->modified) { if (!edit_query_dialog2 (_("Warning"), _("Current text was modified without a file save.\n" "Continue discards these changes."), _("C&ontinue"), _("&Cancel"))) { edit->force |= REDRAW_COMPLETELY; do_moveto = 1; } } else { do_moveto = 1; } if (curr && do_moveto) { if (edit_stack_iterator + 1 < MAX_HISTORY_MOVETO) { vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); if (edit->dir_vpath != NULL) { edit_history_moveto[edit_stack_iterator].filename_vpath = vfs_path_append_vpath_new (edit->dir_vpath, edit->filename_vpath, NULL); } else { edit_history_moveto[edit_stack_iterator].filename_vpath = vfs_path_clone (edit->filename_vpath); } edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; edit_stack_iterator++; vfs_path_free (edit_history_moveto[edit_stack_iterator].filename_vpath); edit_history_moveto[edit_stack_iterator].filename_vpath = vfs_path_from_str ((char *) curr_def->fullpath); edit_history_moveto[edit_stack_iterator].line = curr_def->line; edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath, edit_history_moveto[edit_stack_iterator].line); } } } /* clear definition hash */ for (i = 0; i < MAX_DEFINITIONS; i++) { g_free (def_hash[i].filename); } /* destroy dialog before return */ dlg_destroy (def_dlg); }
/* Tries to raise file lock Returns 1 on success, 0 on failure, -1 if abort Warning: Might do screen refresh and lose edit->force */ int edit_lock_file (char *fname) { char *lockfname, *newlock, *msg, *lock; struct stat statbuf; struct lock_s *lockinfo; /* Just to be sure (and don't lock new file) */ if (!fname || !*fname) return 0; /* Locking on VFS is not supported */ if (!vfs_file_is_local (fname)) return 0; /* Check if already locked */ lockfname = g_strconcat (".#", fname, NULL); if (lstat (lockfname, &statbuf) == 0) { lock = lock_get_info (lockfname); if (!lock) { g_free (lockfname); return 0; } lockinfo = lock_extract_info (lock); /* Check if locking process alive, ask user if required */ if (!lockinfo->pid || !(kill (lockinfo->pid, 0) == -1 && errno == ESRCH)) { msg = g_strdup_printf (_ ("File \"%s\" is already being edited\n" "User: %s\nProcess ID: %d"), fname, lockinfo->who, lockinfo->pid); /* TODO: Implement "Abort" - needs to rewind undo stack */ switch (edit_query_dialog2 (_("File locked"), msg, _("&Grab lock"), _("&Ignore lock"))) { case 0: break; case 1: case -1: g_free (lockfname); g_free (msg); return 0; } g_free (msg); } unlink (lockfname); } /* Create lock symlink */ newlock = lock_build_name (fname); if (symlink (newlock, lockfname) == -1) { g_free (lockfname); g_free (newlock); return 0; } g_free (lockfname); g_free (newlock); return 1; }