summaryrefslogtreecommitdiff
path: root/plugins/shotwell-publishing/PiwigoPublishing.vala
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-11-25 04:11:58 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-11-25 04:11:58 +0100
commitccff5442184e84d511c2bd25ed3da53e4336a272 (patch)
tree8402a0ba68852e0aec5841ed4519ccfe88352223 /plugins/shotwell-publishing/PiwigoPublishing.vala
parenta1e1833f48ed618273dab9198b547148a89832a7 (diff)
parent4a3f1fdfe1eb3743564adcee35d5513224339260 (diff)
Merge tag 'upstream/0.25.1'
Upstream version 0.25.1
Diffstat (limited to 'plugins/shotwell-publishing/PiwigoPublishing.vala')
-rw-r--r--plugins/shotwell-publishing/PiwigoPublishing.vala440
1 files changed, 202 insertions, 238 deletions
diff --git a/plugins/shotwell-publishing/PiwigoPublishing.vala b/plugins/shotwell-publishing/PiwigoPublishing.vala
index 0b98f05..ca07554 100644
--- a/plugins/shotwell-publishing/PiwigoPublishing.vala
+++ b/plugins/shotwell-publishing/PiwigoPublishing.vala
@@ -85,6 +85,10 @@ internal class Category {
public bool is_local() {
return this.id == NO_ID;
}
+
+ public static bool equal (Category self, Category other) {
+ return self.id == other.id;
+ }
}
internal class PermissionLevel {
@@ -613,35 +617,29 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
string name = "";
string id_string = "";
string uppercats = "";
+ var id_map = new Gee.HashMap<string, string> ();
+
for ( ; category_node_iter != null; category_node_iter = category_node_iter->next) {
name_node = doc.get_named_child(category_node_iter, "name");
name = name_node->get_content();
uppercats_node = doc.get_named_child(category_node_iter, "uppercats");
uppercats = (string)uppercats_node->get_content();
id_string = category_node_iter->get_prop("id");
+ id_map.set (id_string, name);
+
if (categories == null) {
categories = new Category[0];
}
categories += new Category(int.parse(id_string), name, uppercats);
}
+
// compute the display name for the categories
- // currently done by an unnecessary triple loop
- // one could make a loop that goes over the categories
- // and creates a list of back references cat_id -> index
- // but since cat_ids are not guaranteed to be continuous
- // that needs a perl hash ;-)
for(int i = 0; i < categories.length; i++) {
string[] upcatids = categories[i].uppercats.split(",");
var builder = new StringBuilder();
for (int j=0; j < upcatids.length; j++) {
builder.append ("/ ");
- // search for the upper category
- for (int k=0; k < categories.length; k++) {
- if (upcatids[j] == categories[k].id.to_string()) {
- builder.append (categories[k].name);
- break;
- }
- }
+ builder.append (id_map.get (upcatids[j]));
builder.append (" ");
}
categories[i].display_name = builder.str;
@@ -1005,158 +1003,148 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader {
// UI elements
-internal class SSLErrorPane : Spit.Publishing.DialogPane, Object {
- private Gtk.Builder builder;
- private Gtk.Widget content;
+internal class SSLErrorPane : Shotwell.Plugins.Common.BuilderPane {
public signal void proceed ();
+ public string host { owned get; construct; }
+ public TlsCertificate cert { private get; construct; }
+ public string error_text { owned get; construct; }
public SSLErrorPane (SessionLoginTransaction transaction,
string host) {
- try {
- TlsCertificate cert;
- this.builder = new Gtk.Builder ();
- this.builder.add_from_resource (Resources.RESOURCE_PATH +
- "/piwigo_ssl_failure_pane.ui");
- this.content = this.builder.get_object ("content") as Gtk.Widget;
- var label = this.builder.get_object ("main_text") as Gtk.Label;
- // %s is the host name that we tried to connect to
- label.set_text (_("This does not look like the real <b>%s</b>. Attackers might be trying to steal or alter information going to or from this site (for example, private messages, credit card information, or passwords).").printf (host));
- label.use_markup = true;
-
- label = this.builder.get_object ("ssl_errors") as Gtk.Label;
- var text = transaction.detailed_error_from_tls_flags (out cert);
- label.set_text (text);
-
- var info = this.builder.get_object ("default") as Gtk.Button;
- info.clicked.connect (() => {
- var simple_cert = new Gcr.SimpleCertificate (cert.certificate.data);
- var widget = new Gcr.CertificateWidget (simple_cert);
-
- var dialog = new Gtk.Dialog ();
- dialog.get_content_area ().add (widget);
- dialog.add_button ("_OK", Gtk.ResponseType.OK);
- dialog.set_default_response (Gtk.ResponseType.OK);
- dialog.set_default_size (640, -1);
- dialog.show_all ();
- dialog.run ();
- dialog.destroy ();
- });
-
- var proceed = this.builder.get_object ("proceed_button") as Gtk.Button;
- proceed.clicked.connect (() => { this.proceed (); });
-
- if (this.content.parent != null) {
- this.content.parent.remove (this.content);
+ TlsCertificate cert;
+ var text = transaction.detailed_error_from_tls_flags (out cert);
+ Object (resource_path : Resources.RESOURCE_PATH +
+ "/piwigo_ssl_failure_pane.ui",
+ default_id: "default",
+ cert : cert,
+ error_text : text,
+ host : host);
+ }
+
+ public override void constructed () {
+ base.constructed ();
+
+ var label = this.get_builder ().get_object ("main_text") as Gtk.Label;
+ // %s is the host name that we tried to connect to
+ label.set_text (_("This does not look like the real <b>%s</b>. Attackers might be trying to steal or alter information going to or from this site (for example, private messages, credit card information, or passwords).").printf (host));
+ label.use_markup = true;
+
+ label = this.get_builder ().get_object ("ssl_errors") as Gtk.Label;
+ label.set_text (error_text);
+
+ var info = this.get_builder ().get_object ("default") as Gtk.Button;
+ info.clicked.connect (() => {
+ var simple_cert = new Gcr.SimpleCertificate (cert.certificate.data);
+ var widget = new Gcr.CertificateWidget (simple_cert);
+ bool use_header = true;
+ Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header);
+ var flags = (Gtk.DialogFlags) 0;
+ if (use_header) {
+ flags |= Gtk.DialogFlags.USE_HEADER_BAR;
}
- } catch (Error error) {
- warning ("Failed to create ui file: %s", error.message);
- assert_not_reached ();
- }
- }
- public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry () {
- return Spit.Publishing.DialogPane.GeometryOptions.NONE;
- }
-
- public Gtk.Widget get_widget () {
- return this.content;
- }
+ var dialog = new Gtk.Dialog.with_buttons (
+ _("Certificate of %s").printf (host),
+ null,
+ flags,
+ _("_OK"), Gtk.ResponseType.OK);
+ dialog.get_content_area ().add (widget);
+ dialog.set_default_response (Gtk.ResponseType.OK);
+ dialog.set_default_size (640, -1);
+ dialog.show_all ();
+ dialog.run ();
+ dialog.destroy ();
+ });
- public Gtk.Widget get_default_widget () {
- return this.builder.get_object ("default") as Gtk.Widget;
+ var proceed = this.get_builder ().get_object ("proceed_button") as Gtk.Button;
+ proceed.clicked.connect (() => { this.proceed (); });
}
-
- public void on_pane_installed () { }
-
- public void on_pane_uninstalled () { }
}
/**
* The authentication pane used when asking service URL, user name and password
* from the user.
*/
-internal class AuthenticationPane : Spit.Publishing.DialogPane, Object {
+internal class AuthenticationPane : Shotwell.Plugins.Common.BuilderPane {
public enum Mode {
INTRO,
FAILED_RETRY_URL,
FAILED_RETRY_USER
}
+
+ public Mode mode { get; construct; }
+ public unowned PiwigoPublisher publisher { get; construct; }
+
private static string INTRO_MESSAGE = _("Enter the URL of your Piwigo photo library as well as the username and password associated with your Piwigo account for that library.");
private static string FAILED_RETRY_URL_MESSAGE = _("Shotwell cannot contact your Piwigo photo library. Please verify the URL you entered");
private static string FAILED_RETRY_USER_MESSAGE = _("Username and/or password invalid. Please try again");
- private Gtk.Box pane_widget = null;
- private Gtk.Builder builder;
private Gtk.Entry url_entry;
private Gtk.Entry username_entry;
private Gtk.Entry password_entry;
- private Gtk.CheckButton remember_password_checkbutton;
+ private Gtk.Switch remember_password_checkbutton;
private Gtk.Button login_button;
public signal void login(string url, string user, string password, bool remember_password);
- public AuthenticationPane(PiwigoPublisher publisher, Mode mode = Mode.INTRO) {
- this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+ public AuthenticationPane (PiwigoPublisher publisher, Mode mode = Mode.INTRO) {
+ Object (resource_path : Resources.RESOURCE_PATH +
+ "/piwigo_authentication_pane.ui",
+ connect_signals : true,
+ default_id : "login_button",
+ mode : mode,
+ publisher : publisher);
+ }
- try {
- builder = new Gtk.Builder();
- builder.add_from_resource (Resources.RESOURCE_PATH + "/piwigo_authentication_pane.ui");
- builder.connect_signals(null);
- Gtk.Alignment align = builder.get_object("alignment") as Gtk.Alignment;
-
- Gtk.Label message_label = builder.get_object("message_label") as Gtk.Label;
- switch (mode) {
- case Mode.INTRO:
- message_label.set_text(INTRO_MESSAGE);
- break;
-
- case Mode.FAILED_RETRY_URL:
- message_label.set_markup("<b>%s</b>\n\n%s".printf(_(
- "Invalid URL"), FAILED_RETRY_URL_MESSAGE));
- break;
-
- case Mode.FAILED_RETRY_USER:
- message_label.set_markup("<b>%s</b>\n\n%s".printf(_(
- "Invalid User Name or Password"), FAILED_RETRY_USER_MESSAGE));
- break;
- }
+ public override void constructed () {
+ base.constructed ();
- url_entry = builder.get_object ("url_entry") as Gtk.Entry;
- string? persistent_url = publisher.get_persistent_url();
- if (persistent_url != null) {
- url_entry.set_text(persistent_url);
- }
- username_entry = builder.get_object ("username_entry") as Gtk.Entry;
- string? persistent_username = publisher.get_persistent_username();
- if (persistent_username != null) {
- username_entry.set_text(persistent_username);
- }
- password_entry = builder.get_object ("password_entry") as Gtk.Entry;
- string? persistent_password = publisher.get_persistent_password();
- if (persistent_password != null) {
- password_entry.set_text(persistent_password);
- }
- remember_password_checkbutton =
- builder.get_object ("remember_password_checkbutton") as Gtk.CheckButton;
- remember_password_checkbutton.set_active(publisher.get_remember_password());
+ var builder = this.get_builder ();
+ var message_label = builder.get_object("message_label") as Gtk.Label;
+ switch (mode) {
+ case Mode.INTRO:
+ message_label.set_text(INTRO_MESSAGE);
+ break;
- login_button = builder.get_object("login_button") as Gtk.Button;
+ case Mode.FAILED_RETRY_URL:
+ message_label.set_markup("<b>%s</b>\n\n%s".printf(_(
+ "Invalid URL"), FAILED_RETRY_URL_MESSAGE));
+ break;
- username_entry.changed.connect(on_user_changed);
- url_entry.changed.connect(on_url_changed);
- password_entry.changed.connect(on_password_changed);
- login_button.clicked.connect(on_login_button_clicked);
+ case Mode.FAILED_RETRY_USER:
+ message_label.set_markup("<b>%s</b>\n\n%s".printf(_(
+ "Invalid User Name or Password"), FAILED_RETRY_USER_MESSAGE));
+ break;
+ }
- align.reparent(pane_widget);
- publisher.get_host().set_dialog_default_widget(login_button);
- } catch (Error e) {
- warning("Could not load UI: %s", e.message);
+ url_entry = builder.get_object ("url_entry") as Gtk.Entry;
+ string? persistent_url = publisher.get_persistent_url();
+ if (persistent_url != null) {
+ url_entry.set_text(persistent_url);
}
- }
-
- public Gtk.Widget get_default_widget() {
- return login_button;
+ username_entry = builder.get_object ("username_entry") as Gtk.Entry;
+ string? persistent_username = publisher.get_persistent_username();
+ if (persistent_username != null) {
+ username_entry.set_text(persistent_username);
+ }
+ password_entry = builder.get_object ("password_entry") as Gtk.Entry;
+ string? persistent_password = publisher.get_persistent_password();
+ if (persistent_password != null) {
+ password_entry.set_text(persistent_password);
+ }
+ remember_password_checkbutton =
+ builder.get_object ("remember_password_checkbutton") as Gtk.Switch;
+ remember_password_checkbutton.set_active(publisher.get_remember_password());
+
+ login_button = builder.get_object("login_button") as Gtk.Button;
+
+ username_entry.changed.connect(on_user_changed);
+ url_entry.changed.connect(on_url_changed);
+ password_entry.changed.connect(on_password_changed);
+ login_button.clicked.connect(on_login_button_clicked);
+
+ publisher.get_host().set_dialog_default_widget(login_button);
}
private void on_login_button_clicked() {
@@ -1182,34 +1170,23 @@ internal class AuthenticationPane : Spit.Publishing.DialogPane, Object {
password_entry.text_length != 0);
}
- public Gtk.Widget get_widget() {
- return pane_widget;
- }
-
- public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() {
- return Spit.Publishing.DialogPane.GeometryOptions.NONE;
- }
-
- public void on_pane_installed() {
+ public override void on_pane_installed() {
+ base.on_pane_installed ();
+
url_entry.grab_focus();
password_entry.set_activates_default(true);
login_button.can_default = true;
update_login_button_sensitivity();
}
-
- public void on_pane_uninstalled() {
- }
}
/**
* The publishing options pane.
*/
-internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
+internal class PublishingOptionsPane : Shotwell.Plugins.Common.BuilderPane {
private static string DEFAULT_CATEGORY_NAME = _("Shotwell Connect");
- private Gtk.Box pane_widget = null;
- private Gtk.Builder builder;
private Gtk.RadioButton use_existing_radio;
private Gtk.RadioButton create_new_radio;
private Gtk.ComboBoxText existing_categories_combo;
@@ -1225,88 +1202,88 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
private Gtk.Button publish_button;
private Gtk.TextView album_comment;
private Gtk.Label album_comment_label;
-
- private Category[] existing_categories;
+
private PermissionLevel[] perm_levels;
private SizeEntry[] photo_sizes;
-
- private int last_category;
- private int last_permission_level;
- private int last_photo_size;
- private bool last_title_as_comment;
- private bool last_no_upload_tags;
+
+ public int last_category { private get; construct; }
+ public int last_permission_level { private get; construct; }
+ public int last_photo_size { private get; construct; }
+ public bool last_title_as_comment { private get; construct; }
+ public bool last_no_upload_tags { private get; construct; }
+ public bool strip_metadata_enabled { private get; construct; }
+ public Gee.List<Category> existing_categories { private get; construct; }
+ public string default_comment { private get; construct; }
public signal void publish(PublishingParameters parameters, bool strip_metadata);
public signal void logout();
- public PublishingOptionsPane(
- PiwigoPublisher publisher, Category[] categories,
- int last_category, int last_permission_level, int last_photo_size,
- bool last_title_as_comment, bool last_no_upload_tags, bool strip_metadata_enabled
- ) {
- this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
- this.last_category = last_category;
- this.last_permission_level = last_permission_level;
- this.last_photo_size = last_photo_size;
- this.last_title_as_comment = last_title_as_comment;
- this.last_no_upload_tags = last_no_upload_tags;
+ public PublishingOptionsPane(PiwigoPublisher publisher,
+ Category[] categories,
+ int last_category,
+ int last_permission_level,
+ int last_photo_size,
+ bool last_title_as_comment,
+ bool last_no_upload_tags,
+ bool strip_metadata_enabled) {
+ Object (resource_path : Resources.RESOURCE_PATH +
+ "/piwigo_publishing_options_pane.ui",
+ connect_signals : true,
+ default_id : "publish_button",
+ last_category : last_category,
+ last_permission_level : last_permission_level,
+ last_photo_size : last_photo_size,
+ last_title_as_comment : last_title_as_comment,
+ last_no_upload_tags : last_no_upload_tags,
+ strip_metadata_enabled : strip_metadata_enabled,
+ existing_categories : new Gee.ArrayList<Category>.wrap (categories,
+ Category.equal),
+ default_comment : get_common_comment_if_possible (publisher));
+ }
+
+ public override void constructed () {
+ base.constructed ();
+ var builder = this.get_builder ();
+
+ use_existing_radio = builder.get_object("use_existing_radio") as Gtk.RadioButton;
+ create_new_radio = builder.get_object("create_new_radio") as Gtk.RadioButton;
+ existing_categories_combo = builder.get_object("existing_categories_combo") as Gtk.ComboBoxText;
+ new_category_entry = builder.get_object ("new_category_entry") as Gtk.Entry;
+ within_existing_label = builder.get_object ("within_existing_label") as Gtk.Label;
+ within_existing_combo = builder.get_object ("within_existing_combo") as Gtk.ComboBoxText;
+
+ album_comment = builder.get_object ("album_comment") as Gtk.TextView;
+ album_comment.buffer = new Gtk.TextBuffer(null);
+ album_comment_label = builder.get_object ("album_comment_label") as Gtk.Label;
+
+ perms_combo = builder.get_object("perms_combo") as Gtk.ComboBoxText;
+ size_combo = builder.get_object("size_combo") as Gtk.ComboBoxText;
+
+ strip_metadata_check = builder.get_object("strip_metadata_check") as Gtk.CheckButton;
+ strip_metadata_check.set_active(strip_metadata_enabled);
+
+ title_as_comment_check = builder.get_object("title_as_comment_check") as Gtk.CheckButton;
+ title_as_comment_check.set_active(last_title_as_comment);
+
+ no_upload_tags_check = builder.get_object("no_upload_tags_check") as Gtk.CheckButton;
+ no_upload_tags_check.set_active(last_no_upload_tags);
+
+ logout_button = builder.get_object("logout_button") as Gtk.Button;
+ logout_button.clicked.connect(on_logout_button_clicked);
+
+ publish_button = builder.get_object("publish_button") as Gtk.Button;
+ publish_button.clicked.connect(on_publish_button_clicked);
+
+ use_existing_radio.clicked.connect(on_use_existing_radio_clicked);
+ create_new_radio.clicked.connect(on_create_new_radio_clicked);
+ new_category_entry.changed.connect(on_new_category_entry_changed);
+ within_existing_combo.changed.connect(on_existing_combo_changed);
- try {
- builder = new Gtk.Builder();
- builder.add_from_resource (Resources.RESOURCE_PATH + "/piwigo_publishing_options_pane.ui");
- builder.connect_signals(null);
- Gtk.Alignment align = builder.get_object("alignment") as Gtk.Alignment;
-
- use_existing_radio = builder.get_object("use_existing_radio") as Gtk.RadioButton;
- create_new_radio = builder.get_object("create_new_radio") as Gtk.RadioButton;
- existing_categories_combo = builder.get_object("existing_categories_combo") as Gtk.ComboBoxText;
- new_category_entry = builder.get_object ("new_category_entry") as Gtk.Entry;
- within_existing_label = builder.get_object ("within_existing_label") as Gtk.Label;
- within_existing_combo = builder.get_object ("within_existing_combo") as Gtk.ComboBoxText;
-
- album_comment = builder.get_object ("album_comment") as Gtk.TextView;
- album_comment.buffer = new Gtk.TextBuffer(null);
- album_comment_label = builder.get_object ("album_comment_label") as Gtk.Label;
-
- perms_combo = builder.get_object("perms_combo") as Gtk.ComboBoxText;
- size_combo = builder.get_object("size_combo") as Gtk.ComboBoxText;
-
- strip_metadata_check = builder.get_object("strip_metadata_check") as Gtk.CheckButton;
- strip_metadata_check.set_active(strip_metadata_enabled);
-
- title_as_comment_check = builder.get_object("title_as_comment_check") as Gtk.CheckButton;
- title_as_comment_check.set_active(last_title_as_comment);
-
- no_upload_tags_check = builder.get_object("no_upload_tags_check") as Gtk.CheckButton;
- no_upload_tags_check.set_active(last_no_upload_tags);
-
- logout_button = builder.get_object("logout_button") as Gtk.Button;
- logout_button.clicked.connect(on_logout_button_clicked);
-
- publish_button = builder.get_object("publish_button") as Gtk.Button;
- publish_button.clicked.connect(on_publish_button_clicked);
-
- use_existing_radio.clicked.connect(on_use_existing_radio_clicked);
- create_new_radio.clicked.connect(on_create_new_radio_clicked);
- new_category_entry.changed.connect(on_new_category_entry_changed);
- within_existing_combo.changed.connect(on_existing_combo_changed);
-
- align.reparent(pane_widget);
- pane_widget.set_child_packing(align, true, true, 0, Gtk.PackType.START);
- } catch (Error e) {
- warning("Could not load UI: %s", e.message);
- }
-
- this.existing_categories = categories;
this.perm_levels = create_perm_levels();
this.photo_sizes = create_sizes();
- this.album_comment.buffer.set_text(get_common_comment_if_possible(publisher));
- }
-
- public Gtk.Widget get_default_widget() {
- return publish_button;
+ this.album_comment.buffer.set_text(this.default_comment);
}
-
+
private PermissionLevel[] create_perm_levels() {
PermissionLevel[] result = new PermissionLevel[0];
@@ -1410,16 +1387,10 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
)
);
}
-
- public Gtk.Widget get_widget() {
- return pane_widget;
- }
-
- public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() {
- return Spit.Publishing.DialogPane.GeometryOptions.NONE;
- }
-
- public void on_pane_installed() {
+
+ public override void on_pane_installed() {
+ base.on_pane_installed ();
+
create_categories_combo();
create_within_categories_combo();
create_permissions_combo();
@@ -1428,8 +1399,8 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
publish_button.can_default = true;
update_publish_button_sensitivity();
}
-
- private string get_common_comment_if_possible(PiwigoPublisher publisher) {
+
+ private static string get_common_comment_if_possible(PiwigoPublisher publisher) {
// we have to determine whether all the publishing items
// belong to the same event
Spit.Publishing.Publishable[] publishables = publisher.get_host().get_publishables();
@@ -1462,7 +1433,7 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
foreach (Category cat in existing_categories) {
existing_categories_combo.append_text(cat.display_name);
}
- if (existing_categories.length == 0) {
+ if (existing_categories.is_empty) {
// if no existing categories, disable the option to choose one
existing_categories_combo.set_sensitive(false);
use_existing_radio.set_sensitive(false);
@@ -1472,11 +1443,7 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
new_category_entry.grab_focus();
} else {
int last_category_index = find_category_index(last_category);
- if (last_category_index < 0) {
- existing_categories_combo.set_active(0);
- } else {
- existing_categories_combo.set_active(last_category_index);
- }
+ existing_categories_combo.set_active(last_category_index);
new_category_entry.set_sensitive(false);
album_comment.set_sensitive(false);
album_comment_label.set_sensitive(false);
@@ -1520,13 +1487,10 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object {
size_combo.set_active(last_size_index);
}
}
-
- public void on_pane_uninstalled() {
- }
-
+
private int find_category_index(int category_id) {
- int result = -1;
- for(int i = 0; i < existing_categories.length; i++) {
+ int result = 0;
+ for(int i = 0; i < existing_categories.size; i++) {
if (existing_categories[i].id == category_id) {
result = i;
break;