В этом посте я расскажу о простом блокноте на языке программирования Vala. Программа создавалась с использованием среды разработки GNOME Builder и редактора интерфейсов Glade.
Внешний вид
Вот так приложение выглядит:
Слева можно видеть список всех заметок, которые автоматически сохраняются в специальной папке. Имя по умолчанию для любой заметки имеет вид даты и времени ее создания. Нажав на последнюю кнопку в хидербаре, можно назначить другое имя. Исходный код приложения находится здесь.
Иерархия элементов интерфейса в редакторе Glade:
Создание заметки
Нажав на первую кнопку, пользователь сразу же создает заметку с именем по умолчанию. За это отвечает следующий метод:
private void on_add_clicked(){ GLib.File file = GLib.File.new_for_path(directory_path+"/"+date_time()); try { FileUtils.set_contents (file.get_path(), "");//создаем пустой файл } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } if(!is_empty(text_view.buffer.text)){ text_view.buffer.text = ""; } show_notes();//показываем список заметок }
Метод date_time
, который дает имя заметке:
private string date_time(){ var now = new DateTime.now_local (); return now.format("%d")+"."+now.format("%m")+"."+now.format("%Y")+" "+now.format("%H")+":"+now.format("%M")+":"+now.format("%S"); }
Идем дальше. Метод для показа списка:
private void show_notes () { list_store.clear(); list = new GLib.List<string> (); try { Dir dir = Dir.open (directory_path, 0); string? file_name = null; while ((file_name = dir.read_name ()) != null) { list.append(file_name); } } catch (FileError err) { stderr.printf (err.message); } Gtk.TreeIter iter; foreach (string item in list) { list_store.append(out iter); list_store.set(iter, Columns.TEXT, item); } }
Метод вызывается каждый раз, когда нужно обновить список.
Удаление заметки
За удаление заметок отвечает вот такой метод:
private void on_delete_clicked(){ var selection = tree_view.get_selection(); selection.set_mode(Gtk.SelectionMode.SINGLE); Gtk.TreeModel model; Gtk.TreeIter iter; if (!selection.get_selected(out model, out iter)) { alert("Choose a note"); return; } GLib.File file = GLib.File.new_for_path(directory_path+"/"+item); var dialog_delete_file = new Gtk.MessageDialog(this, Gtk.DialogFlags.MODAL,Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, "Delete note "+file.get_basename()+" ?"); dialog_delete_file.set_title("Question"); Gtk.ResponseType result = (Gtk.ResponseType)dialog_delete_file.run (); dialog_delete_file.destroy(); if(result==Gtk.ResponseType.OK){ FileUtils.remove (directory_path+"/"+item);//удаляем файл if(file.query_exists()){ alert("Delete failed");//не получилось удалить }else{ show_notes(); text_view.buffer.text = "";//очищаем текстовую область } } }
Удаление происходит только после подтверждения этого действия пользователем.
Сохранение заметок
Для сохранение заметок существует следующий код:
private void on_save_clicked(){ var selection = tree_view.get_selection(); selection.set_mode(Gtk.SelectionMode.SINGLE); Gtk.TreeModel model; Gtk.TreeIter iter; if (!selection.get_selected(out model, out iter)) { alert("Choose a note"); return; } if(is_empty(text_view.buffer.text)){ alert("Nothing to save"); return; } GLib.File file = GLib.File.new_for_path(directory_path+"/"+item); var dialog_save_file = new Gtk.MessageDialog(this, Gtk.DialogFlags.MODAL,Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, "Save note "+file.get_basename()+" ?"); dialog_save_file.set_title("Question"); Gtk.ResponseType result = (Gtk.ResponseType)dialog_save_file.run (); if(result==Gtk.ResponseType.OK){ try { FileUtils.set_contents (file.get_path(), text_view.buffer.text);//записываем в файл содержимое текстовой области } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } show_notes(); } dialog_save_file.destroy(); }
Здесь, при сохранении сначала идет проверка, а есть ли вообще, что сохранять. В случае, если текст не обнаружен, пользователь получает соответствующее сообщение.
Сохранение заметок под другим именем
Для того чтобы поменять имя заметки используется такой метод:
private void on_save_as_clicked(){ var selection = tree_view.get_selection(); selection.set_mode(Gtk.SelectionMode.SINGLE); Gtk.TreeModel model; Gtk.TreeIter iter; if (!selection.get_selected(out model, out iter)) { alert("Choose a note");//нужно выбрать заметку из списка return; } if(is_empty(text_view.buffer.text)){ alert("Nothing to save");//нечего сохранять return; } var dialog_save_note = new Gtk.Dialog.with_buttons ("Save note", this, Gtk.DialogFlags.MODAL);var content_area = dialog_save_note.get_content_area (); entry_name = new Gtk.Entry(); var label_name = new Gtk.Label.with_mnemonic ("_Name:"); var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 20); hbox.set_border_width(15); hbox.pack_start (label_name, false, true, 0); hbox.pack_start (entry_name, true, true, 0);content_area.add (hbox);dialog_save_note.add_button ("OK", Gtk.ResponseType.OK);dialog_save_note.add_button ("CLOSE", Gtk.ResponseType.CLOSE);dialog_save_note.response.connect (on_save_response);dialog_save_note.show_all (); }
В вышеприведенном коде создается простенькое диалоговое окно для ввода нового имени заметки:
Для обработки нажатий на кнопки OK и CLOSE понадобится метод
on_save_response
:
private void on_save_response (Gtk.Dialog dialog, int response_id) { switch (response_id) {case Gtk.ResponseType.OK:if(is_empty(entry_name.get_text())){ alert("Enter the name");//нужно ввести имя entry_name.grab_focus(); return;}GLib.File select_file = GLib.File.new_for_path(directory_path+"/"+item);GLib.File edit_file = GLib.File.new_for_path(directory_path+"/"+entry_name.get_text().strip());if (select_file.get_basename() != edit_file.get_basename() && !edit_file.query_exists()){ FileUtils.rename(select_file.get_path(), edit_file.get_path());//переименовываем файл if(!edit_file.query_exists()){ alert("Rename failed");//не получилось переименовать return; } try { FileUtils.set_contents (edit_file.get_path(), text_view.buffer.text); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } }else{ if (select_file.get_basename() != edit_file.get_basename()) { alert("A note with the same name already exists");//такое имя уже есть entry_name.grab_focus(); return; } try { FileUtils.set_contents (edit_file.get_path(), text_view.buffer.text); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } } show_notes(); dialog.destroy();break;case Gtk.ResponseType.CLOSE: dialog.destroy(); break;case Gtk.ResponseType.DELETE_EVENT:dialog.destroy();break;}}
Обязательно нужно проверить существует ли заметка с таким же именем и если существует, то предложить пользователю ввести другое имя.
Отображение текста заметки
Чтобы показать содержимое заметки используется такой код:
private void on_select_item () { var selection = tree_view.get_selection(); selection.set_mode(Gtk.SelectionMode.SINGLE); Gtk.TreeModel model; Gtk.TreeIter iter; if (!selection.get_selected(out model, out iter)) { return; } Gtk.TreePath path = model.get_path(iter); var index = int.parse(path.to_string()); if (index >= 0) { item = list.nth_data(index); } string text; try { FileUtils.get_contents (directory_path+"/"+item, out text); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); } text_view.buffer.text = text;//показываем текст заметки }
На этом все! До встречи в следующих постах!
Дата-центр ITSOFT размещение и аренда серверов и стоек в двух дата-центрах в Москве. За последние годы UPTIME 100%. Размещение GPU-ферм и ASIC-майнеров, аренда GPU-серверов, лицензии связи, SSL-сертификаты, администрирование серверов и поддержка сайтов.