diff --git a/ShareX.HelpersLib/Colors/GradientInfo.cs b/ShareX.HelpersLib/Colors/GradientInfo.cs index 5fa99cf47..cb2b02e21 100644 --- a/ShareX.HelpersLib/Colors/GradientInfo.cs +++ b/ShareX.HelpersLib/Colors/GradientInfo.cs @@ -38,13 +38,7 @@ public class GradientInfo public List Colors { get; set; } - public bool IsValid - { - get - { - return Colors != null && Colors.Count >= 2 && Colors.Any(x => x.Location == 0f) && Colors.Any(x => x.Location == 100f); - } - } + public bool IsValid => Colors != null && Colors.Count > 0; public GradientInfo() { @@ -52,6 +46,21 @@ public GradientInfo() Colors = new List(); } + public void Sort() + { + Colors.Sort((x, y) => x.Location.CompareTo(y.Location)); + } + + public void Reverse() + { + Colors.Reverse(); + + foreach (GradientStop color in Colors) + { + color.Location = 100 - color.Location; + } + } + public void Draw(Graphics g, Rectangle rect) { if (IsValid) @@ -71,10 +80,21 @@ public void Draw(Graphics g, Rectangle rect) public ColorBlend GetColorBlend() { + List colors = new List(Colors.OrderBy(x => x.Location)); + + if (!colors.Any(x => x.Location == 0)) + { + colors.Insert(0, new GradientStop(colors[0].Color, 0f)); + } + + if (!colors.Any(x => x.Location == 100)) + { + colors.Add(new GradientStop(colors[colors.Count - 1].Color, 100f)); + } + ColorBlend colorBlend = new ColorBlend(); - IEnumerable gradient = Colors.OrderBy(x => x.Location); - colorBlend.Colors = gradient.Select(x => x.Color).ToArray(); - colorBlend.Positions = gradient.Select(x => x.Location / 100).ToArray(); + colorBlend.Colors = colors.Select(x => x.Color).ToArray(); + colorBlend.Positions = colors.Select(x => x.Location / 100).ToArray(); return colorBlend; } diff --git a/ShareX.HelpersLib/Colors/GradientStop.cs b/ShareX.HelpersLib/Colors/GradientStop.cs index 213ca0c58..0ee5dbf0e 100644 --- a/ShareX.HelpersLib/Colors/GradientStop.cs +++ b/ShareX.HelpersLib/Colors/GradientStop.cs @@ -32,7 +32,7 @@ namespace ShareX.HelpersLib public class GradientStop { [DefaultValue(typeof(Color), "Black"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] - public Color Color { get; set; } + public Color Color { get; set; } = Color.Black; private float location; @@ -51,7 +51,6 @@ public float Location public GradientStop() { - this.ApplyDefaultPropertyValues(); } public GradientStop(Color color, float offset) diff --git a/ShareX.HelpersLib/Forms/GradientPickerForm.Designer.cs b/ShareX.HelpersLib/Forms/GradientPickerForm.Designer.cs index 253d48961..88a8b32aa 100644 --- a/ShareX.HelpersLib/Forms/GradientPickerForm.Designer.cs +++ b/ShareX.HelpersLib/Forms/GradientPickerForm.Designer.cs @@ -28,9 +28,11 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GradientPickerForm)); this.lvGradientPoints = new System.Windows.Forms.ListView(); this.chLocation = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.ilColors = new System.Windows.Forms.ImageList(this.components); this.btnAdd = new System.Windows.Forms.Button(); this.btnRemove = new System.Windows.Forms.Button(); this.nudLocation = new System.Windows.Forms.NumericUpDown(); @@ -41,6 +43,7 @@ private void InitializeComponent() this.btnCancel = new System.Windows.Forms.Button(); this.pbPreview = new System.Windows.Forms.PictureBox(); this.lblPreview = new System.Windows.Forms.Label(); + this.btnReverse = new System.Windows.Forms.Button(); this.cbtnCurrentColor = new ShareX.HelpersLib.ColorButton(); ((System.ComponentModel.ISupportInitialize)(this.nudLocation)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pbPreview)).BeginInit(); @@ -55,6 +58,7 @@ private void InitializeComponent() this.lvGradientPoints.HideSelection = false; resources.ApplyResources(this.lvGradientPoints, "lvGradientPoints"); this.lvGradientPoints.Name = "lvGradientPoints"; + this.lvGradientPoints.SmallImageList = this.ilColors; this.lvGradientPoints.UseCompatibleStateImageBehavior = false; this.lvGradientPoints.View = System.Windows.Forms.View.Details; this.lvGradientPoints.SelectedIndexChanged += new System.EventHandler(this.lvGradientPoints_SelectedIndexChanged); @@ -64,6 +68,12 @@ private void InitializeComponent() // resources.ApplyResources(this.chLocation, "chLocation"); // + // ilColors + // + this.ilColors.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; + resources.ApplyResources(this.ilColors, "ilColors"); + this.ilColors.TransparentColor = System.Drawing.Color.Transparent; + // // btnAdd // resources.ApplyResources(this.btnAdd, "btnAdd"); @@ -130,6 +140,13 @@ private void InitializeComponent() resources.ApplyResources(this.lblPreview, "lblPreview"); this.lblPreview.Name = "lblPreview"; // + // btnReverse + // + resources.ApplyResources(this.btnReverse, "btnReverse"); + this.btnReverse.Name = "btnReverse"; + this.btnReverse.UseVisualStyleBackColor = true; + this.btnReverse.Click += new System.EventHandler(this.btnReverse_Click); + // // cbtnCurrentColor // this.cbtnCurrentColor.Color = System.Drawing.Color.White; @@ -144,6 +161,7 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Window; this.CancelButton = this.btnCancel; + this.Controls.Add(this.btnReverse); this.Controls.Add(this.pbPreview); this.Controls.Add(this.lblPreview); this.Controls.Add(this.btnCancel); @@ -181,5 +199,7 @@ private void InitializeComponent() private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.PictureBox pbPreview; private System.Windows.Forms.Label lblPreview; + private System.Windows.Forms.Button btnReverse; + private System.Windows.Forms.ImageList ilColors; } } \ No newline at end of file diff --git a/ShareX.HelpersLib/Forms/GradientPickerForm.cs b/ShareX.HelpersLib/Forms/GradientPickerForm.cs index 8ce6ce954..315747ca3 100644 --- a/ShareX.HelpersLib/Forms/GradientPickerForm.cs +++ b/ShareX.HelpersLib/Forms/GradientPickerForm.cs @@ -45,10 +45,20 @@ public GradientPickerForm(GradientInfo gradient) cbGradientType.Items.AddRange(Helpers.GetEnumNamesProper()); cbGradientType.SelectedIndex = (int)Gradient.Type; + UpdateGradientList(); + } + + private void UpdateGradientList() + { + Gradient.Sort(); + + isReady = false; + lvGradientPoints.Items.Clear(); foreach (GradientStop gradientStop in Gradient.Colors) { AddGradientStop(gradientStop); } + isReady = true; UpdatePreview(); } @@ -73,77 +83,141 @@ private void UpdatePreview() } } + private void AddGradientStop(GradientStop gradientStop) + { + ListViewItem lvi = new ListViewItem(); + lvi.Text = string.Format(" {0:0.##}%", gradientStop.Location); + UpdateListViewItemColor(lvi, gradientStop.Color); + lvi.Tag = gradientStop; + lvGradientPoints.Items.Add(lvi); + } + + private void UpdateListViewItemColor(ListViewItem lvi, Color color) + { + string argb = color.ToArgb().ToString(); + + if (!ilColors.Images.ContainsKey(argb)) + { + ilColors.Images.Add(argb, ImageHelpers.CreateColorPickerIcon(color, new Rectangle(0, 0, 16, 16))); + } + + lvi.ImageKey = argb; + } + + private GradientStop GetSelectedGradientStop() + { + return GetSelectedGradientStop(out _); + } + + private GradientStop GetSelectedGradientStop(out ListViewItem lvi) + { + if (lvGradientPoints.SelectedItems.Count > 0) + { + lvi = lvGradientPoints.SelectedItems[0]; + return lvi.Tag as GradientStop; + } + + lvi = null; + return null; + } + + private ListViewItem FindListViewItem(GradientStop gradientStop) + { + foreach (ListViewItem lvi in lvGradientPoints.Items) + { + GradientStop itemGradientstop = lvi.Tag as GradientStop; + if (itemGradientstop == gradientStop) + { + return lvi; + } + } + + return null; + } + + private ListViewItem SelectGradientStop(GradientStop gradientStop) + { + ListViewItem lvi = FindListViewItem(gradientStop); + if (lvi != null) + { + lvi.Selected = true; + } + return lvi; + } + private void cbGradientType_SelectedIndexChanged(object sender, EventArgs e) { Gradient.Type = (LinearGradientMode)cbGradientType.SelectedIndex; UpdatePreview(); } - private void AddGradientStop(GradientStop gradientStop) - { - ListViewItem lvi = new ListViewItem(); - lvi.Text = string.Format(" {0:0.##}%", gradientStop.Location); - lvi.BackColor = gradientStop.Color; - lvi.ForeColor = ColorHelpers.VisibleColor(gradientStop.Color); - lvi.Tag = gradientStop; - lvGradientPoints.Items.Add(lvi); - } - private void btnAdd_Click(object sender, EventArgs e) { Color color = cbtnCurrentColor.Color; - float offset = (float)(nudLocation.Value / 100); + float offset = (float)nudLocation.Value; GradientStop gradientStop = new GradientStop(color, offset); Gradient.Colors.Add(gradientStop); - AddGradientStop(gradientStop); - UpdatePreview(); + UpdateGradientList(); + SelectGradientStop(gradientStop); } private void btnRemove_Click(object sender, EventArgs e) { - if (lvGradientPoints.SelectedItems.Count > 0) + GradientStop gradientStop = GetSelectedGradientStop(); + + if (gradientStop != null) { - ListViewItem lvi = lvGradientPoints.SelectedItems[0]; - GradientStop gradientStop = (GradientStop)lvi.Tag; Gradient.Colors.Remove(gradientStop); - lvGradientPoints.Items.Remove(lvi); - UpdatePreview(); + UpdateGradientList(); + } + } + + private void btnReverse_Click(object sender, EventArgs e) + { + if (Gradient.IsValid) + { + Gradient.Reverse(); + UpdateGradientList(); } } private void cbtnCurrentColor_ColorChanged(Color color) { - if (lvGradientPoints.SelectedItems.Count > 0) + GradientStop gradientStop = GetSelectedGradientStop(out ListViewItem lvi); + + if (gradientStop != null) { - ListViewItem lvi = lvGradientPoints.SelectedItems[0]; - GradientStop gradientStop = (GradientStop)lvi.Tag; gradientStop.Color = color; - lvi.BackColor = gradientStop.Color; - lvi.ForeColor = ColorHelpers.VisibleColor(gradientStop.Color); + UpdateListViewItemColor(lvi, gradientStop.Color); UpdatePreview(); } } private void nudLocation_ValueChanged(object sender, EventArgs e) { - if (lvGradientPoints.SelectedItems.Count > 0) + if (isReady) { - ListViewItem lvi = lvGradientPoints.SelectedItems[0]; - GradientStop gradientStop = (GradientStop)lvi.Tag; - gradientStop.Location = (float)nudLocation.Value; - lvi.Text = string.Format(" {0:0.##}%", gradientStop.Location); - UpdatePreview(); + GradientStop gradientStop = GetSelectedGradientStop(out ListViewItem lvi); + + if (gradientStop != null) + { + gradientStop.Location = (float)nudLocation.Value; + UpdateGradientList(); + SelectGradientStop(gradientStop); + } } } private void lvGradientPoints_SelectedIndexChanged(object sender, EventArgs e) { - if (lvGradientPoints.SelectedItems.Count > 0) + GradientStop gradientStop = GetSelectedGradientStop(); + + if (gradientStop != null) { - ListViewItem lvi = lvGradientPoints.SelectedItems[0]; - GradientStop gradientStop = (GradientStop)lvi.Tag; + isReady = false; cbtnCurrentColor.Color = gradientStop.Color; nudLocation.SetValue((decimal)gradientStop.Location); + isReady = true; } } diff --git a/ShareX.HelpersLib/Forms/GradientPickerForm.resx b/ShareX.HelpersLib/Forms/GradientPickerForm.resx index dfa415049..a79c9a190 100644 --- a/ShareX.HelpersLib/Forms/GradientPickerForm.resx +++ b/ShareX.HelpersLib/Forms/GradientPickerForm.resx @@ -126,13 +126,19 @@ - 128, 112 + 128, 8 80, 160 + + 17, 17 + + + 16, 16 + - 1 + 8 lvGradientPoints @@ -144,16 +150,20 @@ $this - 11 + 12 + + + + NoControl - 8, 112 + 8, 8 112, 23 - 3 + 2 Add @@ -168,16 +178,19 @@ $this - 9 + 10 + + + NoControl - 8, 136 + 8, 32 112, 23 - 4 + 3 Remove @@ -192,18 +205,17 @@ $this - 8 + 9 - 64, 188 + 8, 144 - 56, 20 + 112, 20 - 5 + 7 - Center @@ -217,13 +229,16 @@ $this - 7 + 8 True + + NoControl + - 5, 192 + 5, 128 51, 13 @@ -244,16 +259,16 @@ $this - 6 + 7 - 88, 84 + 88, 176 120, 21 - 7 + 10 cbGradientType @@ -265,19 +280,22 @@ $this - 5 + 6 True + + NoControl + - 5, 88 + 5, 180 73, 13 - 8 + 9 Gradient type: @@ -292,7 +310,10 @@ $this - 4 + 5 + + + NoControl 8, 280 @@ -301,7 +322,7 @@ 96, 23 - 9 + 0 OK @@ -316,7 +337,10 @@ $this - 3 + 4 + + + NoControl 112, 280 @@ -325,7 +349,7 @@ 96, 23 - 10 + 1 Cancel @@ -340,10 +364,13 @@ $this - 2 + 3 + + + NoControl - 8, 26 + 8, 224 200, 50 @@ -361,19 +388,22 @@ $this - 0 + 1 True + + NoControl + - 5, 8 + 5, 206 48, 13 - 12 + 11 Preview: @@ -388,16 +418,46 @@ $this - 1 + 2 + + + NoControl + + + 8, 56 + + + 112, 23 + + + 4 + + + Reverse + + + btnReverse + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + NoControl - 8, 160 + 8, 96 112, 24 - 2 + 5 Color @@ -406,13 +466,13 @@ cbtnCurrentColor - ShareX.HelpersLib.ColorButton, ShareX.HelpersLib, Version=13.0.2.0, Culture=neutral, PublicKeyToken=null + ShareX.HelpersLib.ColorButton, ShareX.HelpersLib, Version=13.1.1.0, Culture=neutral, PublicKeyToken=null $this - 10 + 11 True @@ -435,6 +495,12 @@ System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ilColors + + + System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + GradientPickerForm diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.Designer.cs b/ShareX.ImageEffectsLib/ImageEffectsForm.Designer.cs index 2aa194200..6b1146506 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.Designer.cs +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.Designer.cs @@ -54,6 +54,8 @@ private void InitializeComponent() this.btnOK = new System.Windows.Forms.Button(); this.btnUploadImage = new System.Windows.Forms.Button(); this.btnRefresh = new System.Windows.Forms.Button(); + this.btnDuplicatePreset = new System.Windows.Forms.Button(); + this.lblPresets = new System.Windows.Forms.Label(); this.cmsLoadImage.SuspendLayout(); this.SuspendLayout(); // @@ -131,6 +133,7 @@ private void InitializeComponent() this.eiImageEffects.DefaultFileName = null; this.eiImageEffects.Name = "eiImageEffects"; this.eiImageEffects.ObjectType = null; + this.eiImageEffects.SerializationBinder = null; this.eiImageEffects.ExportRequested += new ShareX.HelpersLib.ExportImportControl.ExportEventHandler(this.eiImageEffects_ExportRequested); this.eiImageEffects.ImportRequested += new ShareX.HelpersLib.ExportImportControl.ImportEventHandler(this.eiImageEffects_ImportRequested); // @@ -244,12 +247,26 @@ private void InitializeComponent() this.btnRefresh.UseVisualStyleBackColor = true; this.btnRefresh.Click += new System.EventHandler(this.BtnRefresh_Click); // + // btnDuplicatePreset + // + resources.ApplyResources(this.btnDuplicatePreset, "btnDuplicatePreset"); + this.btnDuplicatePreset.Name = "btnDuplicatePreset"; + this.btnDuplicatePreset.UseVisualStyleBackColor = true; + this.btnDuplicatePreset.Click += new System.EventHandler(this.btnDuplicatePreset_Click); + // + // lblPresets + // + resources.ApplyResources(this.lblPresets, "lblPresets"); + this.lblPresets.Name = "lblPresets"; + // // ImageEffectsForm // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Window; this.CancelButton = this.btnClose; + this.Controls.Add(this.lblPresets); + this.Controls.Add(this.btnDuplicatePreset); this.Controls.Add(this.btnRefresh); this.Controls.Add(this.btnUploadImage); this.Controls.Add(this.btnOK); @@ -264,11 +281,11 @@ private void InitializeComponent() this.Controls.Add(this.btnSaveImage); this.Controls.Add(this.btnDuplicate); this.Controls.Add(this.btnClear); - this.Controls.Add(this.pbResult); this.Controls.Add(this.btnRemove); this.Controls.Add(this.btnAdd); this.Controls.Add(this.pgSettings); this.Controls.Add(this.lvEffects); + this.Controls.Add(this.pbResult); this.Name = "ImageEffectsForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.Shown += new System.EventHandler(this.ImageEffectsForm_Shown); @@ -304,6 +321,8 @@ private void InitializeComponent() private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnUploadImage; private System.Windows.Forms.Button btnRefresh; + private System.Windows.Forms.Button btnDuplicatePreset; + private System.Windows.Forms.Label lblPresets; } } diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.cs b/ShareX.ImageEffectsLib/ImageEffectsForm.cs index 8cf6210ec..646b6b13f 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.cs +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.cs @@ -87,10 +87,7 @@ public void EditorMode() protected void OnImageProcessRequested(Bitmap bmp) { - if (ImageProcessRequested != null) - { - ImageProcessRequested(bmp); - } + ImageProcessRequested?.Invoke(bmp); } private void AddAllEffectsToContextMenu() @@ -260,7 +257,7 @@ private void UpdatePreview() private void UpdateControlStates() { - btnRemovePreset.Enabled = cbPresets.Enabled = txtPresetName.Enabled = btnAdd.Enabled = cbPresets.SelectedIndex > -1; + btnRemovePreset.Enabled = btnDuplicatePreset.Enabled = cbPresets.Enabled = txtPresetName.Enabled = btnAdd.Enabled = cbPresets.SelectedIndex > -1; btnRemove.Enabled = btnDuplicate.Enabled = lvEffects.SelectedItems.Count > 0; btnClear.Enabled = lvEffects.Items.Count > 0; } @@ -452,6 +449,17 @@ private void btnRemovePreset_Click(object sender, EventArgs e) } } + private void btnDuplicatePreset_Click(object sender, EventArgs e) + { + ImageEffectPreset preset = GetSelectedPreset(); + + if (preset != null) + { + ImageEffectPreset presetClone = preset.Copy(); + AddPreset(presetClone); + } + } + private void cbPresets_SelectedIndexChanged(object sender, EventArgs e) { if (!ignorePresetsSelectedIndexChanged) diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.resx b/ShareX.ImageEffectsLib/ImageEffectsForm.resx index 6abc83668..98d7486fc 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.resx +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.resx @@ -130,7 +130,7 @@ - 12 + 15 pgSettings @@ -142,16 +142,16 @@ $this - 19 + 20 - 8, 40 + 408, 40 104, 24 - 7 + 9 Add @@ -166,7 +166,7 @@ $this - 18 + 19 Top, Bottom, Left @@ -181,28 +181,28 @@ 168, 424 - 11 + 14 lvEffects - ShareX.HelpersLib.MyListView, ShareX.HelpersLib, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null + ShareX.HelpersLib.MyListView, ShareX.HelpersLib, Version=13.1.1.0, Culture=neutral, PublicKeyToken=null $this - 20 + 21 - 120, 40 + 520, 40 104, 24 - 8 + 10 Remove @@ -217,16 +217,16 @@ $this - 17 + 18 - 344, 40 + 744, 40 104, 24 - 10 + 12 Clear @@ -241,16 +241,16 @@ $this - 15 + 17 - 232, 40 + 632, 40 104, 24 - 9 + 11 Duplicate @@ -265,7 +265,7 @@ $this - 14 + 16 Bottom, Left @@ -280,7 +280,7 @@ 120, 24 - 16 + 19 Save image... @@ -298,7 +298,7 @@ $this - 13 + 15 Bottom, Left @@ -310,19 +310,19 @@ 192, 24 - 14 + 17 eiImageEffects - ShareX.HelpersLib.ExportImportControl, ShareX.HelpersLib, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null + ShareX.HelpersLib.ExportImportControl, ShareX.HelpersLib, Version=13.1.1.0, Culture=neutral, PublicKeyToken=null $this - 12 + 14 Top, Bottom, Left, Right @@ -334,19 +334,19 @@ 432, 424 - 13 + 16 pbResult - ShareX.HelpersLib.MyPictureBox, ShareX.HelpersLib, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null + ShareX.HelpersLib.MyPictureBox, ShareX.HelpersLib, Version=13.1.1.0, Culture=neutral, PublicKeyToken=null $this - 16 + 22 17, 17 @@ -394,7 +394,7 @@ 120, 24 - 15 + 18 Load image @@ -406,22 +406,22 @@ mbLoadImage - ShareX.HelpersLib.MenuButton, ShareX.HelpersLib, Version=13.0.0.0, Culture=neutral, PublicKeyToken=null + ShareX.HelpersLib.MenuButton, ShareX.HelpersLib, Version=13.1.1.0, Culture=neutral, PublicKeyToken=null $this - 11 + 13 - 8, 8 + 408, 8 - 136, 23 + 136, 24 - 2 + 4 New preset @@ -436,16 +436,16 @@ $this - 10 + 12 - 152, 8 + 552, 8 - 136, 23 + 136, 24 - 3 + 5 Remove preset @@ -460,16 +460,16 @@ $this - 9 + 11 - 296, 9 + 104, 10 - 304, 21 + 296, 21 - 4 + 3 cbPresets @@ -481,19 +481,19 @@ $this - 8 + 10 True - 608, 13 + 5, 46 38, 13 - 5 + 7 Name: @@ -508,19 +508,16 @@ $this - 7 - - - Top, Left, Right + 9 - 672, 9 + 104, 42 - 288, 20 + 296, 20 - 6 + 8 txtPresetName @@ -532,7 +529,7 @@ $this - 6 + 8 Bottom, Right @@ -559,7 +556,7 @@ $this - 5 + 7 Bottom, Right @@ -589,7 +586,7 @@ $this - 4 + 6 Bottom, Left @@ -601,7 +598,7 @@ 120, 24 - 17 + 20 Upload image @@ -619,16 +616,16 @@ $this - 3 + 5 - 456, 40 + 856, 40 104, 24 - 18 + 13 Refresh @@ -643,7 +640,58 @@ $this - 0 + 4 + + + 696, 8 + + + 136, 24 + + + 6 + + + Duplicate preset + + + btnDuplicatePreset + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + True + + + 5, 14 + + + 45, 13 + + + 2 + + + Presets: + + + lblPresets + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 True diff --git a/ShareX.UploadersLib/FileUploaders/GoogleDrive.cs b/ShareX.UploadersLib/FileUploaders/GoogleDrive.cs index 30608f9ef..7d33b5eb8 100644 --- a/ShareX.UploadersLib/FileUploaders/GoogleDrive.cs +++ b/ShareX.UploadersLib/FileUploaders/GoogleDrive.cs @@ -52,7 +52,8 @@ public override GenericUploader CreateUploader(UploadersConfig config, TaskRefer { IsPublic = config.GoogleDriveIsPublic, DirectLink = config.GoogleDriveDirectLink, - FolderID = config.GoogleDriveUseFolder ? config.GoogleDriveFolderID : null + FolderID = config.GoogleDriveUseFolder ? config.GoogleDriveFolderID : null, + DriveID = config.GoogleDriveSelectedDrive?.id }; } @@ -75,6 +76,13 @@ public sealed class GoogleDrive : FileUploader, IOAuth2 public bool IsPublic { get; set; } public bool DirectLink { get; set; } public string FolderID { get; set; } + public string DriveID { get; set; } + + public static GoogleDriveSharedDrive MyDrive = new GoogleDriveSharedDrive + { + id = "", // empty defaults to user drive + name = Resources.GoogleDrive_MyDrive_My_drive + }; public GoogleDrive(OAuth2Info oauth) { @@ -106,15 +114,22 @@ public bool GetAccessToken(string code) return GoogleAuth.GetAccessToken(code); } - private string GetMetadata(string name, string parentID) + private string GetMetadata(string name, string parentID, string driveID = "") { object metadata; + // If there's no parent folder, the drive behaves as parent + if (string.IsNullOrEmpty(parentID)) + { + parentID = driveID; + } + if (!string.IsNullOrEmpty(parentID)) { metadata = new { name = name, + driveId = driveID, parents = new[] { parentID @@ -148,7 +163,7 @@ private void SetPermissions(string fileID, GoogleDrivePermissionRole role, Googl string response = SendRequest(HttpMethod.POST, url, json, RequestHelpers.ContentTypeJSON, null, GoogleAuth.GetAuthHeaders()); } - public List GetFolders(bool trashed = false, bool writer = true) + public List GetFolders(string driveID = "", bool trashed = false, bool writer = true) { if (!CheckAuthorization()) return null; @@ -159,7 +174,7 @@ public List GetFolders(bool trashed = false, bool writer = true query += " and trashed = false"; } - if (writer) + if (writer && string.IsNullOrEmpty(driveID)) { query += " and 'me' in writers"; } @@ -167,6 +182,13 @@ public List GetFolders(bool trashed = false, bool writer = true Dictionary args = new Dictionary(); args.Add("q", query); args.Add("fields", "nextPageToken,files(id,name,description)"); + if (!string.IsNullOrEmpty(driveID)) + { + args.Add("driveId", driveID); + args.Add("corpora", "drive"); + args.Add("supportsAllDrives", "true"); + args.Add("includeItemsFromAllDrives", "true"); + } List folders = new List(); string pageToken = ""; @@ -194,14 +216,45 @@ public List GetFolders(bool trashed = false, bool writer = true return folders; } + public List GetDrives() + { + if (!CheckAuthorization()) return null; + + Dictionary args = new Dictionary(); + List drives = new List(); + string pageToken = ""; + + // Make sure we get all the pages of results + do + { + args["pageToken"] = pageToken; + string response = SendRequest(HttpMethod.GET, "https://www.googleapis.com/drive/v3/drives", args, GoogleAuth.GetAuthHeaders()); + pageToken = ""; + + if (!string.IsNullOrEmpty(response)) + { + GoogleDriveSharedDriveList driveList = JsonConvert.DeserializeObject(response); + + if (driveList != null) + { + drives.AddRange(driveList.drives); + pageToken = driveList.nextPageToken; + } + } + } + while (!string.IsNullOrEmpty(pageToken)); + + return drives; + } + public override UploadResult Upload(Stream stream, string fileName) { if (!CheckAuthorization()) return null; - string metadata = GetMetadata(fileName, FolderID); + string metadata = GetMetadata(fileName, FolderID, DriveID); - UploadResult result = SendRequestFile("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,webViewLink,webContentLink", stream, fileName, - "file", headers: GoogleAuth.GetAuthHeaders(), contentType: "multipart/related", relatedData: metadata); + UploadResult result = SendRequestFile("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,webViewLink,webContentLink&supportsAllDrives=true", + stream, fileName, "file", headers: GoogleAuth.GetAuthHeaders(), contentType: "multipart/related", relatedData: metadata); if (!string.IsNullOrEmpty(result.Response)) { @@ -252,4 +305,21 @@ public class GoogleDriveFileList public List files { get; set; } public string nextPageToken { get; set; } } + + public class GoogleDriveSharedDrive + { + public string id { get; set; } + public string name { get; set; } + + public override string ToString() + { + return name; + } + } + + public class GoogleDriveSharedDriveList + { + public List drives { get; set; } + public string nextPageToken { get; set; } + } } \ No newline at end of file diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs b/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs index 98bc9b534..13dafc100 100644 --- a/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs +++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs @@ -189,6 +189,7 @@ private void InitializeComponent() this.cbOneDriveCreateShareableLink = new System.Windows.Forms.CheckBox(); this.oAuth2OneDrive = new ShareX.UploadersLib.OAuthControl(); this.tpGoogleDrive = new System.Windows.Forms.TabPage(); + this.cbGoogleDriveSharedDrive = new System.Windows.Forms.ComboBox(); this.cbGoogleDriveDirectLink = new System.Windows.Forms.CheckBox(); this.cbGoogleDriveUseFolder = new System.Windows.Forms.CheckBox(); this.txtGoogleDriveFolderID = new System.Windows.Forms.TextBox(); @@ -1727,6 +1728,7 @@ private void InitializeComponent() // tpGoogleDrive // this.tpGoogleDrive.BackColor = System.Drawing.SystemColors.Window; + this.tpGoogleDrive.Controls.Add(this.cbGoogleDriveSharedDrive); this.tpGoogleDrive.Controls.Add(this.cbGoogleDriveDirectLink); this.tpGoogleDrive.Controls.Add(this.cbGoogleDriveUseFolder); this.tpGoogleDrive.Controls.Add(this.txtGoogleDriveFolderID); @@ -1738,6 +1740,14 @@ private void InitializeComponent() resources.ApplyResources(this.tpGoogleDrive, "tpGoogleDrive"); this.tpGoogleDrive.Name = "tpGoogleDrive"; // + // cbGoogleDriveSharedDrive + // + this.cbGoogleDriveSharedDrive.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbGoogleDriveSharedDrive.FormattingEnabled = true; + resources.ApplyResources(this.cbGoogleDriveSharedDrive, "cbGoogleDriveSharedDrive"); + this.cbGoogleDriveSharedDrive.Name = "cbGoogleDriveSharedDrive"; + this.cbGoogleDriveSharedDrive.SelectedIndexChanged += new System.EventHandler(this.cbGoogleDriveSharedDrive_SelectedIndexChanged); + // // cbGoogleDriveDirectLink // resources.ApplyResources(this.cbGoogleDriveDirectLink, "cbGoogleDriveDirectLink"); @@ -5651,5 +5661,6 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox cbGoogleCloudStorageStripExtensionImage; private System.Windows.Forms.Label lblB2UrlPreview; private HelpersLib.TabToTreeView tttvMain; + private System.Windows.Forms.ComboBox cbGoogleDriveSharedDrive; } } \ No newline at end of file diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.cs b/ShareX.UploadersLib/Forms/UploadersConfigForm.cs index ad45a6375..4239b38b7 100644 --- a/ShareX.UploadersLib/Forms/UploadersConfigForm.cs +++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.cs @@ -386,6 +386,13 @@ private void LoadFileUploaderSettings() #region Google Drive + cbGoogleDriveSharedDrive.Items.Clear(); + cbGoogleDriveSharedDrive.Items.Add(GoogleDrive.MyDrive); + if (Config.GoogleDriveSelectedDrive?.id != GoogleDrive.MyDrive.id) + { + cbGoogleDriveSharedDrive.Items.Add(Config.GoogleDriveSelectedDrive); + } + if (OAuth2Info.CheckOAuth(Config.GoogleDriveOAuth2Info)) { oauth2GoogleDrive.Status = OAuthLoginStatus.LoginSuccessful; @@ -397,6 +404,7 @@ private void LoadFileUploaderSettings() cbGoogleDriveUseFolder.Checked = Config.GoogleDriveUseFolder; txtGoogleDriveFolderID.Enabled = Config.GoogleDriveUseFolder; txtGoogleDriveFolderID.Text = Config.GoogleDriveFolderID; + GoogleDriveSelectConfigDrive(); #endregion Google Drive @@ -1759,6 +1767,7 @@ private void txtGoogleDriveFolderID_TextChanged(object sender, EventArgs e) private void btnGoogleDriveRefreshFolders_Click(object sender, EventArgs e) { GoogleDriveRefreshFolders(); + GoogleDriveRefreshDrives(); } private void lvGoogleDriveFoldersList_SelectedIndexChanged(object sender, EventArgs e) @@ -1774,6 +1783,12 @@ private void lvGoogleDriveFoldersList_SelectedIndexChanged(object sender, EventA } } + private void cbGoogleDriveSharedDrive_SelectedIndexChanged(object sender, EventArgs e) + { + GoogleDriveSharedDrive selectedDrive = cbGoogleDriveSharedDrive.SelectedItem as GoogleDriveSharedDrive; + Config.GoogleDriveSelectedDrive = selectedDrive; + } + #endregion Google Drive #region puush diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.resx b/ShareX.UploadersLib/Forms/UploadersConfigForm.resx index ea7dea771..f536e84e1 100644 --- a/ShareX.UploadersLib/Forms/UploadersConfigForm.resx +++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.resx @@ -3572,6 +3572,27 @@ when you made the application key. 2 + + 352, 16 + + + 256, 21 + + + 3 + + + cbGoogleDriveSharedDrive + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tpGoogleDrive + + + 0 + True @@ -3585,7 +3606,7 @@ when you made the application key. 93, 17 - 13 + 2 Use direct link @@ -3600,7 +3621,7 @@ when you made the application key. tpGoogleDrive - 0 + 1 True @@ -3609,13 +3630,13 @@ when you made the application key. NoControl - 352, 16 + 352, 47 165, 17 - 12 + 5 Upload files to selected folder @@ -3630,16 +3651,16 @@ when you made the application key. tpGoogleDrive - 1 + 2 352, 88 - 256, 20 + 432, 20 - 9 + 7 txtGoogleDriveFolderID @@ -3651,7 +3672,7 @@ when you made the application key. tpGoogleDrive - 2 + 3 True @@ -3666,7 +3687,7 @@ when you made the application key. 53, 13 - 8 + 6 Folder ID: @@ -3681,7 +3702,7 @@ when you made the application key. tpGoogleDrive - 3 + 4 Title @@ -3702,7 +3723,7 @@ when you made the application key. 432, 352 - 11 + 8 lvGoogleDriveFoldersList @@ -3714,7 +3735,7 @@ when you made the application key. tpGoogleDrive - 4 + 5 False @@ -3723,13 +3744,13 @@ when you made the application key. NoControl - 352, 40 + 616, 15 168, 23 - 10 + 4 Refresh folders list @@ -3744,7 +3765,7 @@ when you made the application key. tpGoogleDrive - 5 + 6 True @@ -3774,7 +3795,7 @@ when you made the application key. tpGoogleDrive - 6 + 7 16, 16 @@ -3795,7 +3816,7 @@ when you made the application key. tpGoogleDrive - 7 + 8 4, 238 diff --git a/ShareX.UploadersLib/Forms/UploadersConfigFormHelper.cs b/ShareX.UploadersLib/Forms/UploadersConfigFormHelper.cs index 04a90deaa..0694c472b 100644 --- a/ShareX.UploadersLib/Forms/UploadersConfigFormHelper.cs +++ b/ShareX.UploadersLib/Forms/UploadersConfigFormHelper.cs @@ -323,7 +323,7 @@ private void GoogleDriveRefreshFolders() if (OAuth2Info.CheckOAuth(Config.GoogleDriveOAuth2Info)) { - List folders = new GoogleDrive(Config.GoogleDriveOAuth2Info).GetFolders(); + List folders = new GoogleDrive(Config.GoogleDriveOAuth2Info).GetFolders(Config.GoogleDriveSelectedDrive.id); if (folders != null) { @@ -343,6 +343,42 @@ private void GoogleDriveRefreshFolders() } } + private void GoogleDriveRefreshDrives() + { + try + { + if (OAuth2Info.CheckOAuth(Config.GoogleDriveOAuth2Info)) + { + List drives = new GoogleDrive(Config.GoogleDriveOAuth2Info).GetDrives(); + + if (drives != null) + { + cbGoogleDriveSharedDrive.Items.Clear(); + cbGoogleDriveSharedDrive.Items.Add(GoogleDrive.MyDrive); + + foreach (GoogleDriveSharedDrive drive in drives) + { + cbGoogleDriveSharedDrive.Items.Add(drive); + } + GoogleDriveSelectConfigDrive(); + } + } + } + catch (Exception ex) + { + ex.ShowError(); + } + } + + private void GoogleDriveSelectConfigDrive() + { + string driveID = Config.GoogleDriveSelectedDrive?.id; + cbGoogleDriveSharedDrive.SelectedItem = cbGoogleDriveSharedDrive.Items + .OfType() + .Where(x => x.id == driveID) + .FirstOrDefault(); + } + #endregion Google Drive #region Box diff --git a/ShareX.UploadersLib/Properties/Resources.Designer.cs b/ShareX.UploadersLib/Properties/Resources.Designer.cs index 00ef58acb..f64bcb7ae 100644 --- a/ShareX.UploadersLib/Properties/Resources.Designer.cs +++ b/ShareX.UploadersLib/Properties/Resources.Designer.cs @@ -285,6 +285,15 @@ internal static System.Drawing.Icon GoogleDrive { } } + /// + /// Looks up a localized string similar to My drive. + /// + internal static string GoogleDrive_MyDrive_My_drive { + get { + return ResourceManager.GetString("GoogleDrive_MyDrive_My_drive", resourceCulture); + } + } + /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// diff --git a/ShareX.UploadersLib/Properties/Resources.resx b/ShareX.UploadersLib/Properties/Resources.resx index 029243455..64c1b5482 100644 --- a/ShareX.UploadersLib/Properties/Resources.resx +++ b/ShareX.UploadersLib/Properties/Resources.resx @@ -404,4 +404,7 @@ Created folders: ..\Resources\navigation-270-button-white.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + My drive + \ No newline at end of file diff --git a/ShareX.UploadersLib/UploadersConfig.cs b/ShareX.UploadersLib/UploadersConfig.cs index 447267665..0101be9d1 100644 --- a/ShareX.UploadersLib/UploadersConfig.cs +++ b/ShareX.UploadersLib/UploadersConfig.cs @@ -198,6 +198,7 @@ public class UploadersConfig : SettingsBase public bool GoogleDriveDirectLink { get; set; } = false; public bool GoogleDriveUseFolder { get; set; } = false; public string GoogleDriveFolderID { get; set; } = ""; + public GoogleDriveSharedDrive GoogleDriveSelectedDrive { get; set; } = GoogleDrive.MyDrive; #endregion Google Drive diff --git a/ShareX/Forms/ScreenRecordForm.zh-TW.resx b/ShareX/Forms/ScreenRecordForm.zh-TW.resx index 52c375748..16ddcbcb8 100644 --- a/ShareX/Forms/ScreenRecordForm.zh-TW.resx +++ b/ShareX/Forms/ScreenRecordForm.zh-TW.resx @@ -121,7 +121,7 @@ ShareX - 螢幕錄製 - 停止 + 中止 開始