├── .gitattributes
├── .gitignore
├── .gitmodules
├── Installer
├── Bundle.wxs
└── Installer.wixproj
├── README.md
├── Redmine.Client
├── AboutBox.Designer.cs
├── AboutBox.cs
├── AboutBox.resx
├── AttachmentForm.Designer.cs
├── AttachmentForm.cs
├── AttachmentForm.resx
├── BgWork.cs
├── BgWorker.cs
├── ClientExtensionMethods.cs
├── CommitForm.Designer.cs
├── CommitForm.cs
├── CommitForm.resx
├── EditEnumForm.Designer.cs
├── EditEnumForm.cs
├── EditEnumForm.resx
├── EditEnumListForm.Designer.cs
├── EditEnumListForm.cs
├── EditEnumListForm.resx
├── Enumerations.cs
├── IssueForm.Designer.cs
├── IssueForm.cs
├── IssueForm.resx
├── IssueFormData.cs
├── IssueGridSelectColumns.Designer.cs
├── IssueGridSelectColumns.cs
├── IssueGridSelectColumns.resx
├── Languages
│ ├── Lang.Designer.cs
│ ├── Lang.cs-CZ.resx
│ ├── Lang.de.resx
│ ├── Lang.es-MX.resx
│ ├── Lang.fr.resx
│ ├── Lang.gl.resx
│ ├── Lang.nl.resx
│ ├── Lang.pl.resx
│ ├── Lang.pt-BR.resx
│ ├── Lang.resx
│ ├── Lang.ru.resx
│ ├── Lang.zh-CN.resx
│ └── LangTools.cs
├── MainFormData.cs
├── OpenSpecificIssueForm.Designer.cs
├── OpenSpecificIssueForm.cs
├── OpenSpecificIssueForm.resx
├── Program.cs
├── ProjectMember.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.resx
│ ├── Resources1.Designer.cs
│ ├── Settings.Designer.cs
│ ├── Settings.cs
│ ├── Settings.settings
│ └── app.config
├── Redmine.Client.csproj
├── RedmineClientForm.Designer.cs
├── RedmineClientForm.cs
├── RedmineClientForm.resx
├── SettingsForm.Designer.cs
├── SettingsForm.cs
├── SettingsForm.resx
├── TimeEntriesForm.Designer.cs
├── TimeEntriesForm.cs
├── TimeEntriesForm.resx
├── TimeEntryForm.Designer.cs
├── TimeEntryForm.cs
├── TimeEntryForm.resx
├── UpdateIssueNoteForm.Designer.cs
├── UpdateIssueNoteForm.cs
├── UpdateIssueNoteForm.resx
├── Utility.cs
├── app.config
└── res
│ ├── aboutclock.png
│ ├── clock-installer.png
│ ├── clock-transparant.png
│ ├── clock.ico
│ └── clock.png
├── RedmineClient.sln
└── Setup
├── Banner.bmp
├── Dialog.bmp
├── License.RedmineClient.rtf
├── Product.wxs
└── Setup.wixproj
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
3 | ### c# and c++ stuff
4 | *.cs text
5 | *.c text
6 | *.cpp text
7 | *.h text
8 | *.hpp text
9 | *.dsp text eol=crlf
10 | *.dsw text eol=crlf
11 | *.vcprops text eol=crlf
12 | *.vcproj text eol=crlf
13 | *.vcxproj text eol=crlf
14 | *.props text eol=crlf
15 | *.sln text eol=crlf
16 | *.vcxproj.filters text eol=crlf
17 | *.rc text=auto
18 | *.rc2 text=auto
19 | resource.h text=auto
20 |
21 | ### Other
22 | *.ps1 text eol=crlf
23 | *.bat text eol=crlf
24 | *.reg text
25 | Makefile text
26 | *.sh text
27 | *.txt text
28 | *.bmp binary
29 | *.png binary
30 | *.jpg binary
31 | *.gif binary
32 | *.xml text
33 | *.wsdl text
34 | *.html text
35 | *.htm text
36 | *.css text
37 | *.js text
38 | *.mib text
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /Redmine.Api
2 | sys$command
3 | bin
4 | obj
5 | *.suo
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Redmine.Api"]
2 | path = Redmine.Api
3 | url = https://github.com/zapadi/redmine-net-api.git
4 |
--------------------------------------------------------------------------------
/Installer/Bundle.wxs:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Installer/Installer.wixproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 3.6
7 | {de8a1716-dea3-4cea-83e5-d24d94519b45}
8 | 2.0
9 | Installer
10 | Bundle
11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
13 | OnBuildSuccess
14 |
15 |
16 | bin\$(Configuration)\
17 | obj\$(Configuration)\
18 | Debug
19 |
20 |
21 | bin\$(Configuration)\
22 | obj\$(Configuration)\
23 |
24 |
25 |
26 |
27 |
28 |
29 | $(WixExtDir)\WixNetFxExtension.dll
30 | WixNetFxExtension
31 |
32 |
33 | $(WixExtDir)\WixBalExtension.dll
34 | WixBalExtension
35 |
36 |
37 |
38 |
39 | Setup
40 | {cae8e32c-d717-4ed3-a795-c5d10fdbe64e}
41 | True
42 | True
43 | Binaries;Content;Satellites
44 | INSTALLFOLDER
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Redmine Desktop Client
2 | Desktop tool for reporting time spent on issues in Redmine project management system.
3 |
4 | You can download it, report bugs, get the source or post feature requests on https://github.com/TheMagician1/redmine-desktop-client
5 |
--------------------------------------------------------------------------------
/Redmine.Client/AboutBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Windows.Forms;
4 |
5 | namespace Redmine.Client
6 | {
7 | partial class AboutBox : Form
8 | {
9 | public AboutBox()
10 | {
11 | InitializeComponent();
12 | //this.Text = String.Format("About {0} {0}", AssemblyTitle);
13 | //this.labelProductName.Text = AssemblyProduct;
14 | this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion);
15 | //this.labelCopyright.Text = AssemblyCopyright;
16 | //this.labelCompanyName.Text = AssemblyCompany;
17 | //this.textBoxDescription.Text = AssemblyDescription;
18 | }
19 |
20 | #region Assembly Attribute Accessors
21 |
22 | public string AssemblyTitle
23 | {
24 | get
25 | {
26 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
27 | if (attributes.Length > 0)
28 | {
29 | AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
30 | if (titleAttribute.Title != "")
31 | {
32 | return titleAttribute.Title;
33 | }
34 | }
35 | return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
36 | }
37 | }
38 |
39 | public string AssemblyVersion
40 | {
41 | get
42 | {
43 | return Assembly.GetExecutingAssembly().GetName().Version.ToString();
44 | }
45 | }
46 |
47 | public string AssemblyDescription
48 | {
49 | get
50 | {
51 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
52 | if (attributes.Length == 0)
53 | {
54 | return "";
55 | }
56 | return ((AssemblyDescriptionAttribute)attributes[0]).Description;
57 | }
58 | }
59 |
60 | public string AssemblyProduct
61 | {
62 | get
63 | {
64 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
65 | if (attributes.Length == 0)
66 | {
67 | return "";
68 | }
69 | return ((AssemblyProductAttribute)attributes[0]).Product;
70 | }
71 | }
72 |
73 | public string AssemblyCopyright
74 | {
75 | get
76 | {
77 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
78 | if (attributes.Length == 0)
79 | {
80 | return "";
81 | }
82 | return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
83 | }
84 | }
85 |
86 | public string AssemblyCompany
87 | {
88 | get
89 | {
90 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
91 | if (attributes.Length == 0)
92 | {
93 | return "";
94 | }
95 | return ((AssemblyCompanyAttribute)attributes[0]).Company;
96 | }
97 | }
98 | #endregion
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Redmine.Client/AboutBox.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Copyright © Pavel Kalian 2009, All rights reserved
122 | Copyright © Bas van Leeuwen 2012-2013
123 |
124 | Other Contributor(s): Johan 't Hart
125 |
126 | Translators:
127 | Blackman82 (Czech); jgoetze && fabismailer (German); rafaelff1 (Portugese (Brazil)); MademoiselleGeek && xtinsive (French); mbouzada (Galician); legal90 (Russian); milek (Polish); gusanito (Spanish (Mexico)); mguo163 (Chinese (China))
128 |
129 |
130 | Redmine Desktop Client
131 | =========
132 |
133 | Desktop tool for reporting time spent on issues in Redmine project management system.
134 |
135 | You can download it, report bugs, get the source or post feature requests on http://code.google.com/p/redmine-desktop-client
136 |
137 | You are free to use this code as much as you wish, but if you make any improvemens, please share them with the community.
138 |
139 | Icons from the excellent Nuvola theme drawn by David Vignoni.
140 |
141 | Copyright (c) 2009, Pavel Kalian
142 | Copyright (c) 2012, Bas van Leeuwen
143 | Other Contributors: Johan 't Hart
144 | All rights reserved.
145 |
146 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
147 |
148 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
149 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
150 | * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
151 |
152 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153 |
154 |
--------------------------------------------------------------------------------
/Redmine.Client/AttachmentForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class AttachmentForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
32 | this.labelAttachmentDescription = new System.Windows.Forms.Label();
33 | this.textBoxDescription = new System.Windows.Forms.TextBox();
34 | this.BtnOKButton = new System.Windows.Forms.Button();
35 | this.BtnCancelButton = new System.Windows.Forms.Button();
36 | this.textBoxAttachmentFilePath = new System.Windows.Forms.TextBox();
37 | this.labelSelectAttachment = new System.Windows.Forms.Label();
38 | this.BtnBrowseButton = new System.Windows.Forms.Button();
39 | this.SuspendLayout();
40 | //
41 | // openFileDialog
42 | //
43 | this.openFileDialog.FileName = "*.*";
44 | //
45 | // labelAttachmentDescription
46 | //
47 | this.labelAttachmentDescription.AutoSize = true;
48 | this.labelAttachmentDescription.Location = new System.Drawing.Point(9, 57);
49 | this.labelAttachmentDescription.Name = "labelAttachmentDescription";
50 | this.labelAttachmentDescription.Size = new System.Drawing.Size(60, 13);
51 | this.labelAttachmentDescription.TabIndex = 17;
52 | this.labelAttachmentDescription.Text = "Description";
53 | //
54 | // textBoxDescription
55 | //
56 | this.textBoxDescription.Location = new System.Drawing.Point(12, 75);
57 | this.textBoxDescription.Name = "textBoxDescription";
58 | this.textBoxDescription.Size = new System.Drawing.Size(366, 20);
59 | this.textBoxDescription.TabIndex = 16;
60 | //
61 | // BtnOKButton
62 | //
63 | this.BtnOKButton.Location = new System.Drawing.Point(125, 101);
64 | this.BtnOKButton.Margin = new System.Windows.Forms.Padding(2);
65 | this.BtnOKButton.Name = "BtnOKButton";
66 | this.BtnOKButton.Size = new System.Drawing.Size(68, 24);
67 | this.BtnOKButton.TabIndex = 14;
68 | this.BtnOKButton.Text = "OK";
69 | this.BtnOKButton.UseVisualStyleBackColor = true;
70 | this.BtnOKButton.Click += new System.EventHandler(this.BtnOKButton_Click);
71 | //
72 | // BtnCancelButton
73 | //
74 | this.BtnCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
75 | this.BtnCancelButton.Location = new System.Drawing.Point(197, 101);
76 | this.BtnCancelButton.Margin = new System.Windows.Forms.Padding(2);
77 | this.BtnCancelButton.Name = "BtnCancelButton";
78 | this.BtnCancelButton.Size = new System.Drawing.Size(68, 24);
79 | this.BtnCancelButton.TabIndex = 15;
80 | this.BtnCancelButton.Text = "Cancel";
81 | this.BtnCancelButton.UseVisualStyleBackColor = true;
82 | //
83 | // textBoxAttachmentFilePath
84 | //
85 | this.textBoxAttachmentFilePath.Location = new System.Drawing.Point(12, 32);
86 | this.textBoxAttachmentFilePath.Name = "textBoxAttachmentFilePath";
87 | this.textBoxAttachmentFilePath.Size = new System.Drawing.Size(293, 20);
88 | this.textBoxAttachmentFilePath.TabIndex = 16;
89 | //
90 | // labelSelectAttachment
91 | //
92 | this.labelSelectAttachment.AutoSize = true;
93 | this.labelSelectAttachment.Location = new System.Drawing.Point(12, 14);
94 | this.labelSelectAttachment.Name = "labelSelectAttachment";
95 | this.labelSelectAttachment.Size = new System.Drawing.Size(80, 13);
96 | this.labelSelectAttachment.TabIndex = 17;
97 | this.labelSelectAttachment.Text = "Attachment File";
98 | //
99 | // BtnBrowseButton
100 | //
101 | this.BtnBrowseButton.Location = new System.Drawing.Point(310, 29);
102 | this.BtnBrowseButton.Margin = new System.Windows.Forms.Padding(2);
103 | this.BtnBrowseButton.Name = "BtnBrowseButton";
104 | this.BtnBrowseButton.Size = new System.Drawing.Size(68, 24);
105 | this.BtnBrowseButton.TabIndex = 15;
106 | this.BtnBrowseButton.Text = "Browse";
107 | this.BtnBrowseButton.UseVisualStyleBackColor = true;
108 | this.BtnBrowseButton.Click += new System.EventHandler(this.buttonBrowse_Click);
109 | //
110 | // AttachmentForm
111 | //
112 | this.AcceptButton = this.BtnOKButton;
113 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
114 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
115 | this.CancelButton = this.BtnCancelButton;
116 | this.ClientSize = new System.Drawing.Size(390, 136);
117 | this.Controls.Add(this.labelSelectAttachment);
118 | this.Controls.Add(this.labelAttachmentDescription);
119 | this.Controls.Add(this.textBoxAttachmentFilePath);
120 | this.Controls.Add(this.textBoxDescription);
121 | this.Controls.Add(this.BtnOKButton);
122 | this.Controls.Add(this.BtnBrowseButton);
123 | this.Controls.Add(this.BtnCancelButton);
124 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
125 | this.Name = "AttachmentForm";
126 | this.ShowIcon = false;
127 | this.ShowInTaskbar = false;
128 | this.Text = "AttachmentForm";
129 | this.ResumeLayout(false);
130 | this.PerformLayout();
131 |
132 | }
133 |
134 | #endregion
135 |
136 | private System.Windows.Forms.OpenFileDialog openFileDialog;
137 | private System.Windows.Forms.Label labelAttachmentDescription;
138 | private System.Windows.Forms.TextBox textBoxDescription;
139 | private System.Windows.Forms.Button BtnOKButton;
140 | private System.Windows.Forms.Button BtnCancelButton;
141 | private System.Windows.Forms.TextBox textBoxAttachmentFilePath;
142 | private System.Windows.Forms.Label labelSelectAttachment;
143 | private System.Windows.Forms.Button BtnBrowseButton;
144 | }
145 | }
--------------------------------------------------------------------------------
/Redmine.Client/AttachmentForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 | using System.IO;
12 | using Microsoft.Win32;
13 |
14 | namespace Redmine.Client
15 | {
16 | public partial class AttachmentForm : Form
17 | {
18 | private DialogType type;
19 | private Issue issue;
20 | public Attachment NewAttachment { get; private set; }
21 |
22 | public AttachmentForm(Issue issue, DialogType type, string path)
23 | {
24 | InitializeComponent();
25 | this.type = type;
26 | this.issue = issue;
27 | textBoxAttachmentFilePath.Text = path;
28 | LangTools.UpdateControlsForLanguage(this.Controls);
29 | this.Text = String.Format(Lang.DlgAttachmentTitle, issue.Id, issue.Subject);
30 | }
31 |
32 | private void buttonBrowse_Click(object sender, EventArgs e)
33 | {
34 | openFileDialog.InitialDirectory = textBoxAttachmentFilePath.Text;
35 | if (openFileDialog.ShowDialog(this) == DialogResult.OK)
36 | textBoxAttachmentFilePath.Text = openFileDialog.FileName;
37 | }
38 |
39 | private void BtnOKButton_Click(object sender, EventArgs e)
40 | {
41 | try
42 | {
43 | if (type == DialogType.Edit)
44 | {
45 | byte[] file = File.ReadAllBytes(textBoxAttachmentFilePath.Text);
46 | Upload uploadedFile = RedmineClientForm.redmine.UploadFile(file);
47 | uploadedFile.FileName = Path.GetFileName(textBoxAttachmentFilePath.Text);
48 | uploadedFile.Description = textBoxDescription.Text;
49 | uploadedFile.ContentType = GetMimeType(Path.GetExtension(textBoxAttachmentFilePath.Text));
50 | issue.Uploads = new List();
51 | issue.Uploads.Add(uploadedFile);
52 | RedmineClientForm.redmine.UpdateObject(issue.Id.ToString(), issue);
53 | }
54 | else
55 | {
56 | NewAttachment = new Attachment
57 | {
58 | ContentUrl = textBoxAttachmentFilePath.Text,
59 | Description = textBoxDescription.Text,
60 | FileName = Path.GetFileName(textBoxAttachmentFilePath.Text),
61 | ContentType = GetMimeType(Path.GetExtension(textBoxAttachmentFilePath.Text)),
62 | FileSize = (int)new FileInfo(textBoxAttachmentFilePath.Text).Length,
63 | Author = new IdentifiableName { Id = RedmineClientForm.Instance.CurrentUser.Id, Name = RedmineClientForm.Instance.CurrentUser.CompleteName() }
64 | };
65 | }
66 | DialogResult = DialogResult.OK;
67 | this.Close();
68 | }
69 | catch (Exception ex)
70 | {
71 | MessageBox.Show(String.Format(Lang.Error_Exception, ex.Message), Lang.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
72 | }
73 | }
74 |
75 |
76 | public static string GetMimeType(string extension)
77 | {
78 | string mimeType = "application/unknown";
79 |
80 | RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(extension.ToLower());
81 |
82 | if(regKey != null)
83 | {
84 | object contentType = regKey.GetValue("Content Type");
85 |
86 | if(contentType != null)
87 | mimeType = contentType.ToString();
88 | }
89 |
90 | return mimeType;
91 | }
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Redmine.Client/AttachmentForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/Redmine.Client/BgWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Redmine.Client
7 | {
8 | ///
9 | /// Class for storing asynchronous functions
10 | ///
11 | public class BgWork
12 | {
13 | ///
14 | /// Constructor of Background work
15 | ///
16 | /// a descriptive name for the job
17 | /// the actual function to call
18 | public BgWork(String name, RunAsync work)
19 | {
20 | m_name = name;
21 | m_work = work;
22 | }
23 | public String m_name;
24 | public RunAsync m_work;
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/Redmine.Client/BgWorker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows.Forms;
6 |
7 | namespace Redmine.Client
8 | {
9 | public delegate void OnDone();
10 | public delegate OnDone RunAsync();
11 |
12 | public class BgWorker : Form
13 | {
14 | private System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
15 | Queue m_WorkQueue = new Queue();
16 | public BgWorker()
17 | {
18 | this.worker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.worker_DoWork);
19 | this.worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.worker_Complete);
20 | }
21 | ///
22 | /// Add a new background job
23 | ///
24 | /// The name used to display in the statusbar when executing this item
25 | /// The function to execute in the background
26 | public void AddBgWork(String name, RunAsync work)
27 | {
28 | m_WorkQueue.Enqueue(new BgWork(name, work));
29 | TriggerWork();
30 | }
31 |
32 | ///
33 | /// Start the background worker to process the workqueue
34 | ///
35 | /// Even if the worker is already started, start the next item
36 | private void TriggerWork(bool bForce = false)
37 | {
38 | if (m_WorkQueue.Count == 0)
39 | return; //No work
40 | if (!bForce && m_WorkQueue.Count != 1)
41 | return; //Already busy...
42 |
43 | worker.RunWorkerAsync(m_WorkQueue.Peek().m_work);
44 | WorkTriggered(m_WorkQueue.Peek());
45 | }
46 |
47 | virtual protected void WorkTriggered(BgWork CurrentWork) {}
48 |
49 | ///
50 | /// Execute the background function
51 | ///
52 | ///
53 | ///
54 | private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
55 | {
56 | if (e.Argument != null)
57 | e.Result = ((RunAsync)e.Argument)();
58 | }
59 |
60 | ///
61 | /// Current Backgroundwork is complete. Start next item.
62 | ///
63 | ///
64 | ///
65 | private void worker_Complete(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
66 | {
67 | if (e.Result != null)
68 | ((OnDone)e.Result)();
69 | m_WorkQueue.Dequeue();
70 | WorkTriggered(null);
71 | TriggerWork(true);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Redmine.Client/ClientExtensionMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.IO;
6 | using System.Xml;
7 | using System.Xml.Serialization;
8 | using Redmine.Net.Api;
9 | using Redmine.Net.Api.Types;
10 | using System.Collections.Specialized;
11 |
12 | namespace Redmine.Client
13 | {
14 | public static class ClientExtensionMethods
15 | {
16 | public static void WriteCollectionAsElement(this XmlWriter writer, IList list, string listname) where T : class
17 | {
18 | var serializer = new XmlSerializer(typeof(T));
19 | writer.WriteStartElement(listname);
20 | foreach (T element in list)
21 | {
22 | serializer.Serialize(writer, element);
23 | }
24 | writer.WriteEndElement();
25 | }
26 |
27 | public static string CompleteName(this User user)
28 | {
29 | string completeName = "";
30 | if (!String.IsNullOrEmpty(user.FirstName))
31 | completeName += user.FirstName;
32 | if (!String.IsNullOrEmpty(user.LastName))
33 | {
34 | if (!String.IsNullOrEmpty(completeName))
35 | completeName += " ";
36 | completeName += user.LastName;
37 | }
38 | return completeName;
39 | }
40 |
41 | public static String ToByteString(this long byteCount)
42 | {
43 | string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
44 | if (byteCount == 0)
45 | return "0" + suf[0];
46 | long bytes = Math.Abs(byteCount);
47 | int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
48 | double num = Math.Round(bytes / Math.Pow(1024, place), 1);
49 | return (Math.Sign(byteCount) * num).ToString() + suf[place];
50 | }
51 |
52 | public static String ToByteString(this int byteCount)
53 | {
54 | long bytes = byteCount;
55 | return bytes.ToByteString();
56 | }
57 |
58 | public static void MoveControl(this System.Windows.Forms.Control control, int diffx, int diffy)
59 | {
60 | System.Drawing.Point loc = control.Location;
61 | loc.X += diffx;
62 | loc.Y += diffy;
63 | control.Location = loc;
64 | }
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Redmine.Client/CommitForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class CommitForm : Form
15 | {
16 | public Issue issue;
17 | public int ticks = 0;
18 | public string Comment;
19 | public int activityId = 0;
20 | public DateTime spentOn;
21 | public bool closeIssue = false;
22 |
23 | public CommitForm(Issue issue, int ticks, string Comment, int activityId, DateTime spentOn)
24 | {
25 | InitializeComponent();
26 | LangTools.UpdateControlsForLanguage(this.Controls);
27 | Text = Lang.CommitConfirmQuestion;
28 |
29 | this.issue = issue;
30 | this.ticks = ticks;
31 | this.Comment = Comment;
32 | this.activityId = activityId;
33 | this.spentOn = spentOn;
34 |
35 | labelProjectContent.Text = issue.Project.Name;
36 | labelIssueContent.Text = String.Format("({0}) {1}", issue.Id, issue.Subject);
37 | if (labelIssueContent.Size.Width > Size.Width - labelIssueContent.Location.X - 15)
38 | this.Size = new Size(labelIssueContent.Location.X + labelIssueContent.Size.Width + 15, this.Size.Height);
39 |
40 | ComboBoxActivity.DataSource = Enumerations.Activities;
41 | ComboBoxActivity.DisplayMember = "Name";
42 | ComboBoxActivity.ValueMember = "Id";
43 | ComboBoxActivity.SelectedValue = activityId;
44 |
45 | labelTimeContent.Text = String.Format("{0:0.##}", (double)ticks / 3600);
46 | labelDateSpentContent.Text = spentOn.ToString(Lang.Culture.DateTimeFormat.ShortDatePattern);
47 |
48 | TextBoxComment.Text = Comment;
49 |
50 | if (RedmineClientForm.RedmineVersion < ApiVersion.V13x)
51 | {
52 | CheckBoxClosesIssue.Enabled = false;
53 | CheckBoxClosesIssue.Visible = false;
54 | }
55 | }
56 |
57 | private void BtnCommitButton_Click(object sender, EventArgs e)
58 | {
59 | Comment = TextBoxComment.Text;
60 | activityId = ((Enumerations.EnumerationItem)ComboBoxActivity.SelectedItem).Id;
61 | closeIssue = CheckBoxClosesIssue.Checked;
62 | DialogResult = DialogResult.OK;
63 | Close();
64 | }
65 |
66 | private void BtnCancelButton_Click(object sender, EventArgs e)
67 | {
68 | if (TextBoxComment.Text != Comment)
69 | {
70 | switch (MessageBox.Show(String.Format(Lang.CommitCancelSaveCommentText, Environment.NewLine), Lang.CommitCancelSaveCommentQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
71 | {
72 | case DialogResult.Cancel:
73 | this.DialogResult = DialogResult.None;
74 | return;
75 | case DialogResult.Yes:
76 | Comment = TextBoxComment.Text;
77 | break;
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Redmine.Client/CommitForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class EditEnumForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.BtnOKButton = new System.Windows.Forms.Button();
32 | this.BtnCancelButton = new System.Windows.Forms.Button();
33 | this.labelEnumId = new System.Windows.Forms.Label();
34 | this.EnumNameTextBox = new System.Windows.Forms.TextBox();
35 | this.EnumIdTextBox = new System.Windows.Forms.MaskedTextBox();
36 | this.labelEnumName = new System.Windows.Forms.Label();
37 | this.EnumIsDefaultCheckBox = new System.Windows.Forms.CheckBox();
38 | this.labelEnumIsDefault = new System.Windows.Forms.Label();
39 | this.SuspendLayout();
40 | //
41 | // BtnOKButton
42 | //
43 | this.BtnOKButton.Location = new System.Drawing.Point(141, 54);
44 | this.BtnOKButton.Margin = new System.Windows.Forms.Padding(2);
45 | this.BtnOKButton.Name = "BtnOKButton";
46 | this.BtnOKButton.Size = new System.Drawing.Size(68, 24);
47 | this.BtnOKButton.TabIndex = 4;
48 | this.BtnOKButton.Text = "OK";
49 | this.BtnOKButton.UseVisualStyleBackColor = true;
50 | this.BtnOKButton.Click += new System.EventHandler(this.BtnOKButton_Click);
51 | //
52 | // BtnCancelButton
53 | //
54 | this.BtnCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
55 | this.BtnCancelButton.Location = new System.Drawing.Point(213, 54);
56 | this.BtnCancelButton.Margin = new System.Windows.Forms.Padding(2);
57 | this.BtnCancelButton.Name = "BtnCancelButton";
58 | this.BtnCancelButton.Size = new System.Drawing.Size(68, 24);
59 | this.BtnCancelButton.TabIndex = 5;
60 | this.BtnCancelButton.Text = "Cancel";
61 | this.BtnCancelButton.UseVisualStyleBackColor = true;
62 | //
63 | // labelEnumId
64 | //
65 | this.labelEnumId.AutoSize = true;
66 | this.labelEnumId.Location = new System.Drawing.Point(9, 13);
67 | this.labelEnumId.Name = "labelEnumId";
68 | this.labelEnumId.Size = new System.Drawing.Size(16, 13);
69 | this.labelEnumId.TabIndex = 0;
70 | this.labelEnumId.Text = "Id";
71 | //
72 | // EnumNameTextBox
73 | //
74 | this.EnumNameTextBox.Location = new System.Drawing.Point(45, 29);
75 | this.EnumNameTextBox.Name = "EnumNameTextBox";
76 | this.EnumNameTextBox.Size = new System.Drawing.Size(235, 20);
77 | this.EnumNameTextBox.TabIndex = 3;
78 | //
79 | // EnumIdTextBox
80 | //
81 | this.EnumIdTextBox.Location = new System.Drawing.Point(12, 29);
82 | this.EnumIdTextBox.Mask = "99";
83 | this.EnumIdTextBox.Name = "EnumIdTextBox";
84 | this.EnumIdTextBox.Size = new System.Drawing.Size(27, 20);
85 | this.EnumIdTextBox.TabIndex = 1;
86 | //
87 | // labelEnumName
88 | //
89 | this.labelEnumName.AutoSize = true;
90 | this.labelEnumName.Location = new System.Drawing.Point(42, 13);
91 | this.labelEnumName.Name = "labelEnumName";
92 | this.labelEnumName.Size = new System.Drawing.Size(35, 13);
93 | this.labelEnumName.TabIndex = 2;
94 | this.labelEnumName.Text = "Name";
95 | //
96 | // EnumIsDefaultCheckBox
97 | //
98 | this.EnumIsDefaultCheckBox.AutoSize = true;
99 | this.EnumIsDefaultCheckBox.Location = new System.Drawing.Point(295, 37);
100 | this.EnumIsDefaultCheckBox.Name = "EnumIsDefaultCheckBox";
101 | this.EnumIsDefaultCheckBox.Size = new System.Drawing.Size(15, 14);
102 | this.EnumIsDefaultCheckBox.TabIndex = 6;
103 | this.EnumIsDefaultCheckBox.UseVisualStyleBackColor = true;
104 | //
105 | // labelEnumIsDefault
106 | //
107 | this.labelEnumIsDefault.AutoSize = true;
108 | this.labelEnumIsDefault.Location = new System.Drawing.Point(287, 13);
109 | this.labelEnumIsDefault.Name = "labelEnumIsDefault";
110 | this.labelEnumIsDefault.Size = new System.Drawing.Size(41, 13);
111 | this.labelEnumIsDefault.TabIndex = 2;
112 | this.labelEnumIsDefault.Text = "Default";
113 | //
114 | // EditEnumForm
115 | //
116 | this.AcceptButton = this.BtnOKButton;
117 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
118 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
119 | this.CancelButton = this.BtnCancelButton;
120 | this.ClientSize = new System.Drawing.Size(334, 90);
121 | this.Controls.Add(this.EnumIsDefaultCheckBox);
122 | this.Controls.Add(this.EnumIdTextBox);
123 | this.Controls.Add(this.EnumNameTextBox);
124 | this.Controls.Add(this.labelEnumIsDefault);
125 | this.Controls.Add(this.labelEnumName);
126 | this.Controls.Add(this.labelEnumId);
127 | this.Controls.Add(this.BtnOKButton);
128 | this.Controls.Add(this.BtnCancelButton);
129 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
130 | this.MaximizeBox = false;
131 | this.MinimizeBox = false;
132 | this.Name = "EditEnumForm";
133 | this.ShowIcon = false;
134 | this.ShowInTaskbar = false;
135 | this.Text = "EditEnumForm";
136 | this.ResumeLayout(false);
137 | this.PerformLayout();
138 |
139 | }
140 |
141 | #endregion
142 |
143 | private System.Windows.Forms.Button BtnOKButton;
144 | private System.Windows.Forms.Button BtnCancelButton;
145 | private System.Windows.Forms.Label labelEnumId;
146 | private System.Windows.Forms.TextBox EnumNameTextBox;
147 | private System.Windows.Forms.MaskedTextBox EnumIdTextBox;
148 | private System.Windows.Forms.Label labelEnumName;
149 | private System.Windows.Forms.CheckBox EnumIsDefaultCheckBox;
150 | private System.Windows.Forms.Label labelEnumIsDefault;
151 | }
152 | }
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class EditEnumForm : Form
15 | {
16 | public enum eFormType
17 | {
18 | New,
19 | Edit,
20 | };
21 | public Enumerations.EnumerationItem enumValue;
22 | private eFormType type;
23 | private string enumName; // the name of the enumeration set.
24 |
25 | public EditEnumForm(string enumName, eFormType type, Enumerations.EnumerationItem enumValue)
26 | {
27 | InitializeComponent();
28 | this.type = type;
29 | this.enumName = enumName;
30 | this.enumValue = enumValue;
31 |
32 | if (this.type == eFormType.Edit)
33 | {
34 | EnumIdTextBox.Text = enumValue.Id.ToString();
35 | EnumNameTextBox.Text = enumValue.Name;
36 | EnumIsDefaultCheckBox.Checked = enumValue.IsDefault;
37 | }
38 | LoadLanguage();
39 | }
40 |
41 | private void LoadLanguage()
42 | {
43 | LangTools.UpdateControlsForLanguage(this.Controls);
44 | if (type == eFormType.New)
45 | this.Text = String.Format(Lang.DlgEditEnumFormTitle_New, enumName);
46 | else
47 | this.Text = String.Format(Lang.DlgEditEnumFormTitle_Edit, enumValue.Name, enumName);
48 | }
49 |
50 | private void BtnOKButton_Click(object sender, EventArgs e)
51 | {
52 | if (String.IsNullOrEmpty(EnumIdTextBox.Text))
53 | {
54 | MessageBox.Show(String.Format(Lang.Error_EnumFieldIsMandatory, labelEnumId.Text), Lang.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
55 | return;
56 | }
57 | if (String.IsNullOrEmpty(EnumNameTextBox.Text))
58 | {
59 | MessageBox.Show(String.Format(Lang.Error_EnumFieldIsMandatory, labelEnumName.Text), Lang.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
60 | return;
61 | }
62 | enumValue.Id = Convert.ToInt32(EnumIdTextBox.Text);
63 | enumValue.Name = EnumNameTextBox.Text;
64 | enumValue.IsDefault = EnumIsDefaultCheckBox.Checked;
65 | this.DialogResult = DialogResult.OK;
66 | this.Close();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumListForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class EditEnumListForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.EnumerationListView = new System.Windows.Forms.ListView();
32 | this.BtnAddButton = new System.Windows.Forms.Button();
33 | this.BtnSaveButton = new System.Windows.Forms.Button();
34 | this.BtnCancelButton = new System.Windows.Forms.Button();
35 | this.BtnModifyButton = new System.Windows.Forms.Button();
36 | this.BtnDeleteButton = new System.Windows.Forms.Button();
37 | this.SuspendLayout();
38 | //
39 | // EnumerationListView
40 | //
41 | this.EnumerationListView.FullRowSelect = true;
42 | this.EnumerationListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
43 | this.EnumerationListView.HideSelection = false;
44 | this.EnumerationListView.Location = new System.Drawing.Point(12, 12);
45 | this.EnumerationListView.MultiSelect = false;
46 | this.EnumerationListView.Name = "EnumerationListView";
47 | this.EnumerationListView.Size = new System.Drawing.Size(296, 84);
48 | this.EnumerationListView.TabIndex = 0;
49 | this.EnumerationListView.UseCompatibleStateImageBehavior = false;
50 | this.EnumerationListView.View = System.Windows.Forms.View.Details;
51 | this.EnumerationListView.VirtualMode = true;
52 | //
53 | // BtnAddButton
54 | //
55 | this.BtnAddButton.Location = new System.Drawing.Point(314, 12);
56 | this.BtnAddButton.Name = "BtnAddButton";
57 | this.BtnAddButton.Size = new System.Drawing.Size(68, 24);
58 | this.BtnAddButton.TabIndex = 1;
59 | this.BtnAddButton.Text = "Add";
60 | this.BtnAddButton.UseVisualStyleBackColor = true;
61 | this.BtnAddButton.Click += new System.EventHandler(this.BtnAddButton_Click);
62 | //
63 | // BtnSaveButton
64 | //
65 | this.BtnSaveButton.Location = new System.Drawing.Point(242, 101);
66 | this.BtnSaveButton.Margin = new System.Windows.Forms.Padding(2);
67 | this.BtnSaveButton.Name = "BtnSaveButton";
68 | this.BtnSaveButton.Size = new System.Drawing.Size(68, 24);
69 | this.BtnSaveButton.TabIndex = 4;
70 | this.BtnSaveButton.Text = "Save";
71 | this.BtnSaveButton.UseVisualStyleBackColor = true;
72 | this.BtnSaveButton.Click += new System.EventHandler(this.BtnSaveButton_Click);
73 | //
74 | // BtnCancelButton
75 | //
76 | this.BtnCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
77 | this.BtnCancelButton.Location = new System.Drawing.Point(314, 101);
78 | this.BtnCancelButton.Margin = new System.Windows.Forms.Padding(2);
79 | this.BtnCancelButton.Name = "BtnCancelButton";
80 | this.BtnCancelButton.Size = new System.Drawing.Size(68, 24);
81 | this.BtnCancelButton.TabIndex = 5;
82 | this.BtnCancelButton.Text = "Cancel";
83 | this.BtnCancelButton.UseVisualStyleBackColor = true;
84 | //
85 | // BtnModifyButton
86 | //
87 | this.BtnModifyButton.Location = new System.Drawing.Point(314, 42);
88 | this.BtnModifyButton.Name = "BtnModifyButton";
89 | this.BtnModifyButton.Size = new System.Drawing.Size(68, 24);
90 | this.BtnModifyButton.TabIndex = 2;
91 | this.BtnModifyButton.Text = "Modify";
92 | this.BtnModifyButton.UseVisualStyleBackColor = true;
93 | this.BtnModifyButton.Click += new System.EventHandler(this.BtnModifyButton_Click);
94 | //
95 | // BtnDeleteButton
96 | //
97 | this.BtnDeleteButton.Location = new System.Drawing.Point(314, 72);
98 | this.BtnDeleteButton.Name = "BtnDeleteButton";
99 | this.BtnDeleteButton.Size = new System.Drawing.Size(68, 24);
100 | this.BtnDeleteButton.TabIndex = 3;
101 | this.BtnDeleteButton.Text = "Delete";
102 | this.BtnDeleteButton.UseVisualStyleBackColor = true;
103 | this.BtnDeleteButton.Click += new System.EventHandler(this.BtnDeleteButton_Click);
104 | //
105 | // EditEnumListForm
106 | //
107 | this.AcceptButton = this.BtnSaveButton;
108 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
109 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
110 | this.CancelButton = this.BtnCancelButton;
111 | this.ClientSize = new System.Drawing.Size(393, 136);
112 | this.Controls.Add(this.BtnSaveButton);
113 | this.Controls.Add(this.BtnCancelButton);
114 | this.Controls.Add(this.BtnDeleteButton);
115 | this.Controls.Add(this.BtnModifyButton);
116 | this.Controls.Add(this.BtnAddButton);
117 | this.Controls.Add(this.EnumerationListView);
118 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
119 | this.MaximizeBox = false;
120 | this.MinimizeBox = false;
121 | this.Name = "EditEnumListForm";
122 | this.ShowIcon = false;
123 | this.ShowInTaskbar = false;
124 | this.Text = "Edit Enumerations";
125 | this.ResumeLayout(false);
126 |
127 | }
128 |
129 | #endregion
130 |
131 | private System.Windows.Forms.ListView EnumerationListView;
132 | private System.Windows.Forms.Button BtnAddButton;
133 | private System.Windows.Forms.Button BtnSaveButton;
134 | private System.Windows.Forms.Button BtnCancelButton;
135 | private System.Windows.Forms.Button BtnModifyButton;
136 | private System.Windows.Forms.Button BtnDeleteButton;
137 | }
138 | }
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumListForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class EditEnumListForm : Form
15 | {
16 |
17 | public List enumeration { get; private set; }
18 | private string enumName;
19 |
20 | public EditEnumListForm(List enumeration, string enumName)
21 | {
22 | InitializeComponent();
23 | this.enumName = enumName;
24 | this.enumeration = enumeration;
25 |
26 | EnumerationListView.Columns.Add("ColumnId", Lang.labelEnumId, 25);
27 | EnumerationListView.Columns.Add("ColumnName", Lang.labelEnumName, 150);
28 | EnumerationListView.Columns.Add("ColumnIsDefault", Lang.labelEnumIsDefault, 150);
29 | EnumerationListView.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(EnumerationListView_RetrieveVirtualItem);
30 | EnumerationListView.SelectedIndexChanged += new EventHandler(EnumerationListView_SelectedIndexChanged);
31 | EnumerationListView.MouseDoubleClick += new MouseEventHandler(EnumerationListView_MouseDoubleClick);
32 | EnumerationListView.VirtualListSize = enumeration.Count;
33 |
34 | LoadLanguage();
35 | }
36 |
37 | private void LoadLanguage()
38 | {
39 | LangTools.UpdateControlsForLanguage(this.Controls);
40 | this.Text = String.Format(Lang.DlgEditEnumListFormTitle, enumName);
41 | }
42 |
43 | void EnumerationListView_MouseDoubleClick(object sender, MouseEventArgs e)
44 | {
45 | BtnModifyButton_Click(null, null);
46 | }
47 |
48 | void EnumerationListView_SelectedIndexChanged(object sender, EventArgs e)
49 | {
50 | BtnDeleteButton.Enabled = EnumerationListView.SelectedIndices.Count != 0;
51 | BtnModifyButton.Enabled = EnumerationListView.SelectedIndices.Count != 0;
52 | }
53 |
54 | public void EnumerationListView_RetrieveVirtualItem(object Sender, RetrieveVirtualItemEventArgs e)
55 | {
56 | if (e.ItemIndex < 0 || e.ItemIndex >= enumeration.Count)
57 | return;
58 | Enumerations.EnumerationItem item = enumeration[e.ItemIndex];
59 | e.Item = new ListViewItem();
60 | e.Item.Text = item.Id.ToString();
61 | e.Item.SubItems.Add(item.Name);
62 | e.Item.SubItems.Add(item.IsDefault.ToString());
63 | }
64 |
65 | private void BtnAddButton_Click(object sender, EventArgs e)
66 | {
67 | EditEnumForm dlg = new EditEnumForm(enumName, EditEnumForm.eFormType.New, new Enumerations.EnumerationItem { Id = 0, Name = "", IsDefault = false });
68 | do
69 | {
70 | DialogResult result = dlg.ShowDialog(this);
71 | if (result != DialogResult.OK)
72 | return;
73 | if (IsUnique(dlg.enumValue))
74 | {
75 | AddItem(dlg.enumValue);
76 | return;
77 | }
78 | if (MessageBox.Show(Lang.Error_EnumMustBeUnique, Lang.Error, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) != DialogResult.OK)
79 | return;
80 | }
81 | while (true);
82 | }
83 |
84 | private void AddItem(Enumerations.EnumerationItem item)
85 | {
86 | enumeration.Add(item);
87 | EnumerationListView.VirtualListSize = enumeration.Count;
88 | }
89 |
90 | private void DeleteItem(Enumerations.EnumerationItem item)
91 | {
92 | enumeration.Remove(item);
93 | EnumerationListView.VirtualListSize = enumeration.Count;
94 | }
95 |
96 | private bool IsUnique(Enumerations.EnumerationItem item)
97 | {
98 | return IsUnique(item, null);
99 | }
100 |
101 | private bool IsUnique(Enumerations.EnumerationItem item, Enumerations.EnumerationItem itemOri)
102 | {
103 | foreach (Enumerations.EnumerationItem real in enumeration)
104 | {
105 | if (itemOri != null)
106 | if (itemOri == real)
107 | continue;
108 | if (real.Id == item.Id ||
109 | String.Compare(item.Name, item.Name, true) == 0 ||
110 | real.IsDefault == item.IsDefault)
111 | return false;
112 | }
113 | return true;
114 | }
115 |
116 | private Enumerations.EnumerationItem GetCurrentSelectedItem()
117 | {
118 | if (EnumerationListView.SelectedIndices.Count != 1)
119 | return null;
120 | return enumeration[EnumerationListView.SelectedIndices[0]];
121 | }
122 |
123 | private void BtnDeleteButton_Click(object sender, EventArgs e)
124 | {
125 | Enumerations.EnumerationItem item = GetCurrentSelectedItem();
126 | if (item == null)
127 | return;
128 | DeleteItem(item);
129 | }
130 |
131 | private void BtnModifyButton_Click(object sender, EventArgs e)
132 | {
133 | Enumerations.EnumerationItem item = GetCurrentSelectedItem();
134 | if (item == null)
135 | return;
136 | EditEnumForm dlg = new EditEnumForm(enumName, EditEnumForm.eFormType.Edit, item);
137 | do
138 | {
139 | DialogResult result = dlg.ShowDialog(this);
140 | if (result != DialogResult.OK)
141 | return;
142 | if (IsUnique(dlg.enumValue, item))
143 | {
144 | UpdateItem(dlg.enumValue, item);
145 | return;
146 | }
147 | if (MessageBox.Show(Lang.Error_EnumMustBeUnique, Lang.Error, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) != DialogResult.OK)
148 | return;
149 | }
150 | while (true);
151 | }
152 |
153 | private void UpdateItem(Enumerations.EnumerationItem newItem, Enumerations.EnumerationItem original)
154 | {
155 | foreach (Enumerations.EnumerationItem item in enumeration)
156 | {
157 | if (original == item)
158 | {
159 | item.Id = newItem.Id;
160 | item.Name = newItem.Name;
161 | item.IsDefault = newItem.IsDefault;
162 | EnumerationListView.Invalidate();
163 | return;
164 | }
165 | }
166 | }
167 |
168 | private void BtnSaveButton_Click(object sender, EventArgs e)
169 | {
170 | this.DialogResult = DialogResult.OK;
171 | this.Close();
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/Redmine.Client/EditEnumListForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/Enumerations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Globalization;
5 | using Redmine.Net.Api;
6 | using Redmine.Net.Api.Types;
7 | using System.IO;
8 | using System.Xml;
9 | using System.Xml.Schema;
10 | using System.Xml.Serialization;
11 | using System.Windows.Forms;
12 | using Redmine.Net.Api.Extensions;
13 |
14 | namespace Redmine.Client
15 | {
16 | ///
17 | /// The enumerations we need that are not available through the Redmine API
18 | ///
19 | public static class Enumerations
20 | {
21 | [XmlRoot("enumeration_item")]
22 | public class EnumerationItem : IXmlSerializable, IEquatable
23 | {
24 | [XmlElement("id")]
25 | public int Id { get; set; }
26 |
27 | [XmlElement("name")]
28 | public string Name { get; set; }
29 |
30 | [XmlElement("is_default")]
31 | public bool IsDefault { get; set; }
32 |
33 | public IdentifiableName ToIdentifiableName()
34 | {
35 | return new IdentifiableName() { Id = this.Id, Name = this.Name };
36 | }
37 |
38 | #region Implementation of IXmlSerializable
39 |
40 | public XmlSchema GetSchema()
41 | {
42 | return null;
43 | }
44 |
45 | ///
46 | /// Generates an object from its XML representation.
47 | ///
48 | /// The stream from which the object is deserialized.
49 | public void ReadXml(XmlReader reader)
50 | {
51 | reader.Read();
52 | while (!reader.EOF)
53 | {
54 | if (reader.IsEmptyElement && !reader.HasAttributes)
55 | {
56 | reader.Read();
57 | continue;
58 | }
59 |
60 | switch (reader.Name)
61 | {
62 | case "id": Id = reader.ReadElementContentAsInt(); break;
63 |
64 | case "name": Name = reader.ReadElementContentAsString(); break;
65 |
66 | case "is_default": IsDefault = reader.ReadElementContentAsBoolean(); break;
67 |
68 | default: reader.Read(); break;
69 | }
70 | }
71 | }
72 |
73 | public void WriteXml(XmlWriter writer)
74 | {
75 | writer.WriteAttributeString("id", Id.ToString(CultureInfo.InvariantCulture));
76 | writer.WriteAttributeString("name", Name);
77 | writer.WriteAttributeString("is_default", IsDefault.ToString(CultureInfo.InvariantCulture));
78 | }
79 |
80 | #endregion Implementation of IXmlSerializable
81 |
82 | #region Implementation of IEquatable
83 |
84 | public bool Equals(EnumerationItem other)
85 | {
86 | if (other == null) return false;
87 |
88 | return Id == other.Id && Name == other.Name && IsDefault == other.IsDefault;
89 | }
90 |
91 | #endregion Implementation of IEquatable
92 | };
93 |
94 | ///
95 | /// Priorities that can be used in issues
96 | ///
97 | public static List IssuePriorities { get; set; }
98 |
99 | ///
100 | /// Activities that can be used to commit time
101 | ///
102 | public static List Activities { get; set; }
103 |
104 | ///
105 | /// Load all enumerations from file
106 | ///
107 | public static void LoadAll()
108 | {
109 | LoadIssuePriorities();
110 | LoadActivities();
111 | }
112 |
113 | public static void LoadIssuePriorities()
114 | {
115 | bool loadDefault = false;
116 | try
117 | {
118 | IssuePriorities = Load("IssuePriorities");
119 | }
120 | catch (Exception) { loadDefault = true; }
121 | if (loadDefault)
122 | {
123 | IssuePriorities = new List {
124 | new EnumerationItem { Id = 3, Name = "Low", IsDefault = false },
125 | new EnumerationItem { Id = 4, Name = "Normal", IsDefault = true },
126 | new EnumerationItem { Id = 5, Name = "High", IsDefault = false },
127 | new EnumerationItem { Id = 6, Name = "Urgent", IsDefault = false },
128 | new EnumerationItem { Id = 7, Name = "Immediate", IsDefault = false }
129 | };
130 | }
131 | }
132 |
133 | public static void LoadActivities()
134 | {
135 | bool loadDefault = false;
136 | try
137 | {
138 | Activities = Load("Activities");
139 | }
140 | catch (Exception) { loadDefault = true; }
141 | if (loadDefault)
142 | {
143 | Activities = new List {
144 | new EnumerationItem { Id = 8, Name = "Design", IsDefault = true },
145 | new EnumerationItem { Id = 9, Name = "Development", IsDefault = false }
146 | };
147 | }
148 | }
149 |
150 | public static List Load(string listName)
151 | {
152 | string fileName = Application.CommonAppDataPath + "\\" + listName + ".xml";
153 | FileStream f = File.OpenRead(fileName);
154 | List list = new List();
155 | using (var xmlReader = new XmlTextReader(f))
156 | {
157 | xmlReader.WhitespaceHandling = WhitespaceHandling.None;
158 | xmlReader.Read();
159 | list = xmlReader.ReadElementContentAsCollection();
160 | }
161 | return list;
162 | }
163 |
164 | public static void SaveAll()
165 | {
166 | SaveIssuePriorities();
167 | SaveActivities();
168 | }
169 |
170 | public static void SaveIssuePriorities()
171 | {
172 | Save(IssuePriorities, "IssuePriorities");
173 | }
174 |
175 | public static void SaveActivities()
176 | {
177 | Save(Activities, "Activities");
178 | }
179 |
180 | public static void Save(IList list, string listName)
181 | {
182 | var xws = new XmlWriterSettings { OmitXmlDeclaration = true };
183 | string fileName = Application.CommonAppDataPath + "\\" + listName + ".xml";
184 |
185 | File.Delete(fileName);
186 | FileStream f = File.OpenWrite(fileName);
187 | using (var xmlWriter = XmlWriter.Create(f, xws))
188 | {
189 | xmlWriter.WriteCollectionAsElement(list, listName);
190 | }
191 | f.Close();
192 | }
193 |
194 | public static void UpdateActivities(IList timeEntryActivities)
195 | {
196 | Activities.Clear();
197 | foreach (TimeEntryActivity ta in timeEntryActivities)
198 | Activities.Add(new EnumerationItem { Id = ta.Id, Name = ta.Name, IsDefault = ta.IsDefault } );
199 | }
200 |
201 | public static void UpdateIssuePriorities(IList issuePriorities)
202 | {
203 | IssuePriorities.Clear();
204 | foreach (IssuePriority ip in issuePriorities)
205 | IssuePriorities.Add(new EnumerationItem { Id = ip.Id, Name = ip.Name, IsDefault = ip.IsDefault });
206 | }
207 |
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/Redmine.Client/IssueFormData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Redmine.Net.Api.Types;
5 |
6 | namespace Redmine.Client
7 | {
8 |
9 | internal class IssueFormData
10 | {
11 | public IList Trackers { get; set; }
12 | public List Categories { get; set; }
13 | public IList Statuses { get; set; }
14 | // public List Priorities { get; set; }
15 | public List Versions { get; set; }
16 | // public List Watchers { get; set; }
17 | public List ProjectMembers { get; set; }
18 | public IList IssuePriorities { get; set; }
19 | public IList TimeEntries { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Redmine.Client/IssueGridSelectColumns.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Client.Languages;
10 | using Redmine.Client.Properties;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class IssueGridSelectColumns : Form
15 | {
16 | public IssueGridSelectColumns()
17 | {
18 | InitializeComponent();
19 | LangTools.UpdateControlsForLanguage(this.Controls);
20 |
21 | radioButtonHideAssignedTo.Checked = !Settings.Default.IssueGridHeader_ShowAssignedTo;
22 | radioButtonShowAssignedTo.Checked = Settings.Default.IssueGridHeader_ShowAssignedTo;
23 | radioButtonHideCategory.Checked = !Settings.Default.IssueGridHeader_ShowCategory;
24 | radioButtonShowCategory.Checked = Settings.Default.IssueGridHeader_ShowCategory;
25 | radioButtonHideParent.Checked = !Settings.Default.IssueGridHeader_ShowParentIssue;
26 | radioButtonShowParent.Checked = Settings.Default.IssueGridHeader_ShowParentIssue;
27 | radioButtonHidePriority.Checked = !Settings.Default.IssueGridHeader_ShowPriority;
28 | radioButtonShowPriority.Checked = Settings.Default.IssueGridHeader_ShowPriority;
29 | radioButtonHideProject.Checked = !Settings.Default.IssueGridHeader_ShowProject;
30 | radioButtonShowProject.Checked = Settings.Default.IssueGridHeader_ShowProject;
31 | radioButtonHideStatus.Checked = !Settings.Default.IssueGridHeader_ShowStatus;
32 | radioButtonShowStatus.Checked = Settings.Default.IssueGridHeader_ShowStatus;
33 | radioButtonHideFixedVersion.Checked = !Settings.Default.IssueGridHeader_ShowFixedVersion;
34 | radioButtonShowFixedVersion.Checked = Settings.Default.IssueGridHeader_ShowFixedVersion;
35 | }
36 |
37 | private void BtnOKButton_Click(object sender, EventArgs e)
38 | {
39 | try
40 | {
41 | Settings.Default.UpdateSetting("IssueGridHeader_ShowAssignedTo", radioButtonShowAssignedTo.Checked);
42 | Settings.Default.UpdateSetting("IssueGridHeader_ShowCategory", radioButtonShowCategory.Checked);
43 | Settings.Default.UpdateSetting("IssueGridHeader_ShowParentIssue", radioButtonShowParent.Checked);
44 | Settings.Default.UpdateSetting("IssueGridHeader_ShowPriority", radioButtonShowPriority.Checked);
45 | Settings.Default.UpdateSetting("IssueGridHeader_ShowProject", radioButtonShowProject.Checked);
46 | Settings.Default.UpdateSetting("IssueGridHeader_ShowStatus", radioButtonShowStatus.Checked);
47 | Settings.Default.UpdateSetting("IssueGridHeader_ShowFixedVersion", radioButtonShowFixedVersion.Checked);
48 | Settings.Default.Save();
49 |
50 | this.DialogResult = DialogResult.OK;
51 | this.Close();
52 | }
53 | catch (Exception ex)
54 | {
55 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
56 | }
57 | }
58 |
59 | private void BtnCancelButton_Click(object sender, EventArgs e)
60 | {
61 | this.DialogResult = DialogResult.Cancel;
62 | this.Close();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Redmine.Client/IssueGridSelectColumns.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/Languages/LangTools.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Globalization;
6 | using System.Windows.Forms;
7 | using Redmine.Net.Api.Types;
8 |
9 | namespace Redmine.Client.Languages
10 | {
11 | internal static class LangTools
12 | {
13 | // public static CultureInfo language = System.Globalization.CultureInfo.CurrentUICulture;
14 |
15 | public static void UpdateControlsForLanguage(Control.ControlCollection formControls)
16 | {
17 | foreach (Control c in formControls)
18 | {
19 | if (!String.IsNullOrEmpty(Lang.ResourceManager.GetString(c.Name, Lang.Culture)))
20 | c.Text = Lang.ResourceManager.GetString(c.Name, Lang.Culture);
21 | if (c.Controls.Count != 0)
22 | UpdateControlsForLanguage(c.Controls);
23 | }
24 | }
25 |
26 | internal static void UpdateControlsForLanguage(ToolStripItemCollection toolStripItems)
27 | {
28 | foreach (ToolStripItem i in toolStripItems)
29 | {
30 | if (!String.IsNullOrEmpty(Lang.ResourceManager.GetString(i.Name, Lang.Culture)))
31 | i.Text = Lang.ResourceManager.GetString(i.Name, Lang.Culture);
32 | }
33 | }
34 | public static string GetTextForApiVersion(ApiVersion apiVersion)
35 | {
36 | return Lang.ResourceManager.GetString("ApiVersion_" + apiVersion.ToString(), Lang.Culture);
37 | }
38 |
39 | public static string GetIssueField(string fieldName)
40 | {
41 | return Lang.ResourceManager.GetString("IssueField_" + fieldName.ToLower(Lang.Culture), Lang.Culture);
42 | }
43 |
44 | public static string CreateUpdatedText(string fieldName, string from, string to)
45 | {
46 | string basicFormatString;
47 | if (from != null && to != null && from != to)
48 | basicFormatString = Lang.UpdatedField_UpdatedTo;
49 | else if (from == null && to != null)
50 | basicFormatString = Lang.UpdatedField_SetTo;
51 | else if (from != null && to == null)
52 | basicFormatString = Lang.UpdatedField_Deleted;
53 | else
54 | return ""; // nothing changed...
55 | return String.Format(basicFormatString, GetIssueField(fieldName), from, to);
56 | }
57 | public static string CreateUpdatedText(string fieldName, IdentifiableName from, IdentifiableName to)
58 | {
59 | return CreateUpdatedText(fieldName, from != null ? from.Name : null, to != null ? to.Name : null);
60 | }
61 | public static string CreateUpdatedText(string fieldName, DateTime? from, DateTime? to, string fmt)
62 | {
63 | return CreateUpdatedText(fieldName, from.HasValue ? from.Value.ToString(fmt, Lang.Culture) : null, to.HasValue ? to.Value.ToString(fmt, Lang.Culture) : null);
64 | }
65 | public static string CreateUpdatedText(string fieldName, float? from, float? to, string fmt)
66 | {
67 | return CreateUpdatedText(fieldName, from.HasValue ? from.Value.ToString(fmt, Lang.Culture) : null, to.HasValue ? to.Value.ToString(fmt, Lang.Culture) : null);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Redmine.Client/OpenSpecificIssueForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class OpenSpecificIssueForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.BtnOKButton = new System.Windows.Forms.Button();
32 | this.BtnCancelButton = new System.Windows.Forms.Button();
33 | this.labelIssueNumberToOpen = new System.Windows.Forms.Label();
34 | this.textBoxIssueNumber = new System.Windows.Forms.TextBox();
35 | this.SuspendLayout();
36 | //
37 | // BtnOKButton
38 | //
39 | this.BtnOKButton.Location = new System.Drawing.Point(153, 40);
40 | this.BtnOKButton.Margin = new System.Windows.Forms.Padding(2);
41 | this.BtnOKButton.Name = "BtnOKButton";
42 | this.BtnOKButton.Size = new System.Drawing.Size(68, 24);
43 | this.BtnOKButton.TabIndex = 2;
44 | this.BtnOKButton.Text = "OK";
45 | this.BtnOKButton.UseVisualStyleBackColor = true;
46 | this.BtnOKButton.Click += new System.EventHandler(this.BtnOKButton_Click);
47 | //
48 | // BtnCancelButton
49 | //
50 | this.BtnCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
51 | this.BtnCancelButton.Location = new System.Drawing.Point(225, 40);
52 | this.BtnCancelButton.Margin = new System.Windows.Forms.Padding(2);
53 | this.BtnCancelButton.Name = "BtnCancelButton";
54 | this.BtnCancelButton.Size = new System.Drawing.Size(68, 24);
55 | this.BtnCancelButton.TabIndex = 3;
56 | this.BtnCancelButton.Text = "Cancel";
57 | this.BtnCancelButton.UseVisualStyleBackColor = true;
58 | //
59 | // labelIssueNumberToOpen
60 | //
61 | this.labelIssueNumberToOpen.AutoSize = true;
62 | this.labelIssueNumberToOpen.Location = new System.Drawing.Point(12, 15);
63 | this.labelIssueNumberToOpen.Name = "labelIssueNumberToOpen";
64 | this.labelIssueNumberToOpen.Size = new System.Drawing.Size(106, 13);
65 | this.labelIssueNumberToOpen.TabIndex = 0;
66 | this.labelIssueNumberToOpen.Text = "Issuenumber to open";
67 | //
68 | // textBoxIssueNumber
69 | //
70 | this.textBoxIssueNumber.Location = new System.Drawing.Point(153, 12);
71 | this.textBoxIssueNumber.MaxLength = 20;
72 | this.textBoxIssueNumber.Name = "textBoxIssueNumber";
73 | this.textBoxIssueNumber.Size = new System.Drawing.Size(95, 20);
74 | this.textBoxIssueNumber.TabIndex = 1;
75 | this.textBoxIssueNumber.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxIssueNumber_KeyPress);
76 | //
77 | // OpenSpecificIssueForm
78 | //
79 | this.AcceptButton = this.BtnOKButton;
80 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
81 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
82 | this.CancelButton = this.BtnCancelButton;
83 | this.ClientSize = new System.Drawing.Size(304, 75);
84 | this.Controls.Add(this.textBoxIssueNumber);
85 | this.Controls.Add(this.labelIssueNumberToOpen);
86 | this.Controls.Add(this.BtnOKButton);
87 | this.Controls.Add(this.BtnCancelButton);
88 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
89 | this.MaximizeBox = false;
90 | this.MinimizeBox = false;
91 | this.Name = "OpenSpecificIssueForm";
92 | this.ShowIcon = false;
93 | this.ShowInTaskbar = false;
94 | this.Text = "OpenSpecificIssueForm";
95 | this.ResumeLayout(false);
96 | this.PerformLayout();
97 |
98 | }
99 |
100 | #endregion
101 |
102 | private System.Windows.Forms.Button BtnOKButton;
103 | private System.Windows.Forms.Button BtnCancelButton;
104 | private System.Windows.Forms.Label labelIssueNumberToOpen;
105 | private System.Windows.Forms.TextBox textBoxIssueNumber;
106 | }
107 | }
--------------------------------------------------------------------------------
/Redmine.Client/OpenSpecificIssueForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Client.Languages;
10 |
11 | namespace Redmine.Client
12 | {
13 | public partial class OpenSpecificIssueForm : Form
14 | {
15 | public OpenSpecificIssueForm()
16 | {
17 | InitializeComponent();
18 | this.Text = Lang.DlgOpenSpecificIssueTitle;
19 | LangTools.UpdateControlsForLanguage(this.Controls);
20 | if (labelIssueNumberToOpen.Size.Width > Size.Width - textBoxIssueNumber.Location.X - labelIssueNumberToOpen.Location.X - 15)
21 | {
22 | if (labelIssueNumberToOpen.Size.Width + textBoxIssueNumber.Size.Width + 15 > Size.Width - labelIssueNumberToOpen.Location.X - 15)
23 | this.Size = new Size(labelIssueNumberToOpen.Location.X + labelIssueNumberToOpen.Size.Width + textBoxIssueNumber.Size.Width + 30, this.Size.Height);
24 | textBoxIssueNumber.Location = new Point(labelIssueNumberToOpen.Location.X + labelIssueNumberToOpen.Size.Width + 10, textBoxIssueNumber.Location.Y);
25 | }
26 | }
27 | private int issueNumber = 0;
28 | public int IssueNumber { get { return issueNumber; } }
29 |
30 | private void textBoxIssueNumber_KeyPress(object sender, KeyPressEventArgs e)
31 | {
32 | if (!RedmineClientForm.CheckNumericValue(new string(e.KeyChar, 1), 0, 9) && e.KeyChar != '\b')
33 | e.Handled = true;
34 | }
35 |
36 | private void BtnOKButton_Click(object sender, EventArgs e)
37 | {
38 | bool success = Int32.TryParse(textBoxIssueNumber.Text, out issueNumber);
39 | if (!success || issueNumber == 0)
40 | {
41 | MessageBox.Show(Lang.Error_ValueOutOfRange, Lang.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
42 | return;
43 | }
44 | this.DialogResult = DialogResult.OK;
45 | this.Close();
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Redmine.Client/OpenSpecificIssueForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Redmine.Client
5 | {
6 | public enum DialogType
7 | {
8 | New,
9 | Edit,
10 | };
11 |
12 | static class Program
13 | {
14 | ///
15 | /// The main entry point for the application.
16 | ///
17 | [STAThread]
18 | static void Main()
19 | {
20 | try
21 | {
22 | AppDomain.CurrentDomain.UnhandledException += new
23 | UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
24 | Application.EnableVisualStyles();
25 | Application.SetCompatibleTextRenderingDefault(false);
26 | }
27 | catch (Exception)
28 | { }
29 | try
30 | {
31 | Application.Run(RedmineClientForm.Instance);
32 | }
33 | catch (Exception ex)
34 | {
35 | MessageBox.Show(ex.Message, "Start Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
36 | }
37 | }
38 |
39 | ///
40 | /// Handler for the weird exceptions we are not handling in our code and especially for the CLR20r3 stuff
41 | ///
42 | ///
43 | ///
44 | static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
45 | {
46 | Exception ex = (Exception)e.ExceptionObject;
47 | Console.WriteLine("Observed unhandled exception: {0}", ex.ToString());
48 | }
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Redmine.Client/ProjectMember.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Redmine.Net.Api.Types;
6 |
7 | namespace Redmine.Client
8 | {
9 | ///
10 | /// Interface for showing Assignee information
11 | ///
12 | public interface IProjectMember
13 | {
14 | ///
15 | /// Gets the id.
16 | ///
17 | /// The id of the assignee.
18 | int Id { get; }
19 |
20 | ///
21 | /// Gets the name.
22 | ///
23 | /// The name of the assignee.
24 | string Name { get; }
25 | }
26 |
27 | public class ProjectMember : IProjectMember
28 | {
29 | private ProjectMembership member;
30 |
31 | public ProjectMember()
32 | {
33 | this.member = new ProjectMembership { User = new IdentifiableName { Id = 0, Name = "" } };
34 | }
35 | public ProjectMember(User user)
36 | {
37 | this.member = new ProjectMembership { User = new IdentifiableName { Id = user.Id, Name = user.CompleteName() } };
38 | }
39 | public ProjectMember(ProjectMembership projectMember)
40 | {
41 | this.member = projectMember;
42 | }
43 | public int Id { get { if (member.User == null) return member.Group.Id; else return member.User.Id; } }
44 | public string Name { get { if (member.User == null) return member.Group.Name; else return member.User.Name; } }
45 | ///
46 | /// Get the inner member of the projectmembership
47 | ///
48 | public ProjectMembership Member { get { return member; } }
49 |
50 | public static ProjectMember MembershipToMember(ProjectMembership projectMember)
51 | {
52 | return new ProjectMember(projectMember);
53 | }
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("RedmineClient")]
8 | [assembly: AssemblyDescription("Redmine desktop client tool")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("RedmineClient")]
12 | [assembly: AssemblyCopyright("Copyright © Pavel Kalian 2009, Copyright © Bas van Leeuwen 2012-2013")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("e2f31721-fc08-48ad-8e6d-715af20484b1")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("2.0.8.0")]
35 | [assembly: AssemblyFileVersion("2.0.8.0")]
36 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\res\clock.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\res\aboutclock.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/Resources1.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Redmine.Client.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Redmine.Client.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap aboutclock {
67 | get {
68 | object obj = ResourceManager.GetObject("aboutclock", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
75 | ///
76 | internal static System.Drawing.Icon clock {
77 | get {
78 | object obj = ResourceManager.GetObject("clock", resourceCulture);
79 | return ((System.Drawing.Icon)(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/Settings.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client.Properties {
2 |
3 |
4 | // This class allows you to handle specific events on the settings class:
5 | // The SettingChanging event is raised before a setting's value is changed.
6 | // The PropertyChanged event is raised after a setting's value is changed.
7 | // The SettingsLoaded event is raised after the setting values are loaded.
8 | // The SettingsSaving event is raised before the setting values are saved.
9 | internal sealed partial class Settings {
10 |
11 | public Settings() {
12 | // // To add event handlers for saving and changing settings, uncomment the lines below:
13 | //
14 | // this.SettingChanging += this.SettingChangingEventHandler;
15 | //
16 | // this.SettingsSaving += this.SettingsSavingEventHandler;
17 | //
18 | }
19 |
20 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
21 | // Add code to handle the SettingChangingEvent event here.
22 | }
23 |
24 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
25 | // Add code to handle the SettingsSaving event here.
26 | }
27 |
28 | public void SetTickingTick(bool ticking, int ticks)
29 | {
30 | Settings.Default.PropertyValues["IsTicking"].PropertyValue = ticking;
31 | Settings.Default.PropertyValues["TickingTicks"].PropertyValue = ticks;
32 | Settings.Default.Save();
33 | }
34 |
35 | public void SetIssueGridSort(string columnName, System.Windows.Forms.SortOrder order)
36 | {
37 | Settings.Default.PropertyValues["IssueGridSortColumn"].PropertyValue = columnName;
38 | Settings.Default.PropertyValues["IssueGridSortOrder"].PropertyValue = order;
39 | Settings.Default.Save();
40 | }
41 | public bool ShowIssueGridColumn(string columnName)
42 | {
43 | if (Settings.Default.PropertyValues["IssueGridHeader_Show" + columnName] != null)
44 | return (bool)Settings.Default.PropertyValues["IssueGridHeader_Show" + columnName].PropertyValue;
45 | return false;
46 | }
47 |
48 | public void UpdateSetting(string settingName, T setting)
49 | {
50 | Settings.Default.PropertyValues[settingName].PropertyValue = setting;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | my username
7 |
8 |
9 | http://redmine.example.org
10 |
11 |
12 | my password
13 |
14 |
15 | True
16 |
17 |
18 | True
19 |
20 |
21 | True
22 |
23 |
24 | True
25 |
26 |
27 | 0
28 |
29 |
30 | 0
31 |
32 |
33 | 540
34 |
35 |
36 | 460
37 |
38 |
39 | 0
40 |
41 |
42 | 0
43 |
44 |
45 | 0
46 |
47 |
48 | en
49 |
50 |
51 | 3
52 |
53 |
54 | 0
55 |
56 |
57 | False
58 |
59 |
60 | False
61 |
62 |
63 | 0
64 |
65 |
66 | False
67 |
68 |
69 | False
70 |
71 |
72 | 0
73 |
74 |
75 | 0
76 |
77 |
78 | 492
79 |
80 |
81 | 374
82 |
83 |
84 | True
85 |
86 |
87 | None
88 |
89 |
90 | Id
91 |
92 |
93 | False
94 |
95 |
96 | False
97 |
98 |
99 | False
100 |
101 |
102 | False
103 |
104 |
105 | False
106 |
107 |
108 | False
109 |
110 |
111 | False
112 |
113 |
114 | xml
115 |
116 |
117 | True
118 |
119 |
120 | True
121 |
122 |
123 |
--------------------------------------------------------------------------------
/Redmine.Client/Properties/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | my username
12 |
13 |
14 | http://redmine.example.org
15 |
16 |
17 | my password
18 |
19 |
20 | True
21 |
22 |
23 | True
24 |
25 |
26 | True
27 |
28 |
29 | True
30 |
31 |
32 | 0
33 |
34 |
35 | 0
36 |
37 |
38 | 0
39 |
40 |
41 | 0
42 |
43 |
44 | 0
45 |
46 |
47 | 0
48 |
49 |
50 | 0
51 |
52 |
53 | en-US
54 |
55 |
56 | 3
57 |
58 |
59 | 0
60 |
61 |
62 | False
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/Redmine.Client/SettingsForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/TimeEntriesForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class TimeEntriesForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.BtnOKButton = new System.Windows.Forms.Button();
32 | this.DataGridViewTimeEntries = new System.Windows.Forms.DataGridView();
33 | this.BtnDeleteButton = new System.Windows.Forms.Button();
34 | this.BtnModifyButton = new System.Windows.Forms.Button();
35 | this.BtnAddButton = new System.Windows.Forms.Button();
36 | ((System.ComponentModel.ISupportInitialize)(this.DataGridViewTimeEntries)).BeginInit();
37 | this.SuspendLayout();
38 | //
39 | // BtnOKButton
40 | //
41 | this.BtnOKButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
42 | this.BtnOKButton.Location = new System.Drawing.Point(192, 235);
43 | this.BtnOKButton.Margin = new System.Windows.Forms.Padding(2);
44 | this.BtnOKButton.Name = "BtnOKButton";
45 | this.BtnOKButton.Size = new System.Drawing.Size(68, 24);
46 | this.BtnOKButton.TabIndex = 26;
47 | this.BtnOKButton.Text = "OK";
48 | this.BtnOKButton.UseVisualStyleBackColor = true;
49 | this.BtnOKButton.Click += new System.EventHandler(this.BtnOKButton_Click);
50 | //
51 | // DataGridViewTimeEntries
52 | //
53 | this.DataGridViewTimeEntries.AllowUserToAddRows = false;
54 | this.DataGridViewTimeEntries.AllowUserToDeleteRows = false;
55 | this.DataGridViewTimeEntries.AllowUserToResizeRows = false;
56 | this.DataGridViewTimeEntries.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
57 | | System.Windows.Forms.AnchorStyles.Left)
58 | | System.Windows.Forms.AnchorStyles.Right)));
59 | this.DataGridViewTimeEntries.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
60 | this.DataGridViewTimeEntries.Location = new System.Drawing.Point(12, 12);
61 | this.DataGridViewTimeEntries.MultiSelect = false;
62 | this.DataGridViewTimeEntries.Name = "DataGridViewTimeEntries";
63 | this.DataGridViewTimeEntries.ReadOnly = true;
64 | this.DataGridViewTimeEntries.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
65 | this.DataGridViewTimeEntries.Size = new System.Drawing.Size(354, 218);
66 | this.DataGridViewTimeEntries.TabIndex = 28;
67 | this.DataGridViewTimeEntries.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.DataGridViewTimeEntries_CellFormatting);
68 | this.DataGridViewTimeEntries.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DataGridViewTimeEntries_CellMouseDoubleClick);
69 | //
70 | // BtnDeleteButton
71 | //
72 | this.BtnDeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
73 | this.BtnDeleteButton.Location = new System.Drawing.Point(372, 72);
74 | this.BtnDeleteButton.Name = "BtnDeleteButton";
75 | this.BtnDeleteButton.Size = new System.Drawing.Size(68, 24);
76 | this.BtnDeleteButton.TabIndex = 31;
77 | this.BtnDeleteButton.Text = "Delete";
78 | this.BtnDeleteButton.UseVisualStyleBackColor = true;
79 | this.BtnDeleteButton.Click += new System.EventHandler(this.BtnDeleteButton_Click);
80 | //
81 | // BtnModifyButton
82 | //
83 | this.BtnModifyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
84 | this.BtnModifyButton.Location = new System.Drawing.Point(372, 42);
85 | this.BtnModifyButton.Name = "BtnModifyButton";
86 | this.BtnModifyButton.Size = new System.Drawing.Size(68, 24);
87 | this.BtnModifyButton.TabIndex = 30;
88 | this.BtnModifyButton.Text = "Modify";
89 | this.BtnModifyButton.UseVisualStyleBackColor = true;
90 | this.BtnModifyButton.Click += new System.EventHandler(this.BtnModifyButton_Click);
91 | //
92 | // BtnAddButton
93 | //
94 | this.BtnAddButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
95 | this.BtnAddButton.Location = new System.Drawing.Point(372, 12);
96 | this.BtnAddButton.Name = "BtnAddButton";
97 | this.BtnAddButton.Size = new System.Drawing.Size(68, 24);
98 | this.BtnAddButton.TabIndex = 29;
99 | this.BtnAddButton.Text = "Add";
100 | this.BtnAddButton.UseVisualStyleBackColor = true;
101 | this.BtnAddButton.Click += new System.EventHandler(this.BtnAddButton_Click);
102 | //
103 | // TimeEntriesForm
104 | //
105 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
106 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
107 | this.ClientSize = new System.Drawing.Size(452, 270);
108 | this.Controls.Add(this.BtnDeleteButton);
109 | this.Controls.Add(this.BtnModifyButton);
110 | this.Controls.Add(this.BtnAddButton);
111 | this.Controls.Add(this.DataGridViewTimeEntries);
112 | this.Controls.Add(this.BtnOKButton);
113 | this.Name = "TimeEntriesForm";
114 | this.ShowIcon = false;
115 | this.ShowInTaskbar = false;
116 | this.Text = "TimeEntriesForm";
117 | this.Load += new System.EventHandler(this.TimeEntriesForm_Load);
118 | ((System.ComponentModel.ISupportInitialize)(this.DataGridViewTimeEntries)).EndInit();
119 | this.ResumeLayout(false);
120 |
121 | }
122 |
123 | #endregion
124 |
125 | private System.Windows.Forms.Button BtnOKButton;
126 | private System.Windows.Forms.DataGridView DataGridViewTimeEntries;
127 | private System.Windows.Forms.Button BtnDeleteButton;
128 | private System.Windows.Forms.Button BtnModifyButton;
129 | private System.Windows.Forms.Button BtnAddButton;
130 | }
131 | }
--------------------------------------------------------------------------------
/Redmine.Client/TimeEntriesForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/TimeEntryForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class TimeEntryForm : BgWorker
15 | {
16 | public enum eFormType
17 | {
18 | New,
19 | Edit,
20 | };
21 | public TimeEntry CurTimeEntry { get; set; }
22 | private Issue issue;
23 | private IList projectMembers;
24 | private eFormType type;
25 |
26 | public TimeEntryForm(Issue issue, IList projectMembers)
27 | {
28 | InitializeComponent();
29 | this.issue = issue;
30 | this.projectMembers = projectMembers;
31 | type = eFormType.New;
32 | CurTimeEntry = new TimeEntry();
33 | LoadLanguage();
34 | LoadCombos();
35 | comboBoxByUser.SelectedValue = RedmineClientForm.Instance.CurrentUser.Id;
36 | }
37 | public TimeEntryForm(Issue issue, IList projectMembers, TimeEntry timeEntry)
38 | {
39 | InitializeComponent();
40 | this.issue = issue;
41 | this.projectMembers = projectMembers;
42 | type = eFormType.Edit;
43 | CurTimeEntry = timeEntry;
44 | LoadLanguage();
45 | LoadCombos();
46 |
47 | if (CurTimeEntry.SpentOn.HasValue)
48 | datePickerSpentOn.Value = CurTimeEntry.SpentOn.Value;
49 |
50 | comboBoxByUser.SelectedValue = CurTimeEntry.User.Id;
51 | comboBoxActivity.SelectedValue = CurTimeEntry.Activity.Id;
52 | textBoxSpentHours.Text = CurTimeEntry.Hours.ToString(Lang.Culture);
53 | textBoxComment.Text = CurTimeEntry.Comments;
54 | }
55 |
56 | private void LoadCombos()
57 | {
58 | comboBoxActivity.DataSource = Enumerations.Activities;
59 | comboBoxActivity.DisplayMember = "Name";
60 | comboBoxActivity.ValueMember = "Id";
61 | foreach (Enumerations.EnumerationItem i in Enumerations.Activities)
62 | {
63 | if (i.IsDefault)
64 | {
65 | comboBoxActivity.SelectedValue = i.Id;
66 | break;
67 | }
68 | }
69 | comboBoxByUser.DataSource = projectMembers;
70 | comboBoxByUser.DisplayMember = "Name";
71 | comboBoxByUser.ValueMember = "Id";
72 | }
73 |
74 | private void LoadLanguage()
75 | {
76 | LangTools.UpdateControlsForLanguage(this.Controls);
77 | if (type == eFormType.New)
78 | {
79 | this.Text = String.Format(Lang.DlgTimeEntryFormTitle_New, issue.Id, issue.Subject);
80 | //there is a mistake in the language-string, so we added the newline also as the third ({2}) element in the format string
81 | labelTimeEntryTitle.Text = String.Format(Lang.labelTimeEntryTitle_New, issue.Id, issue.Subject, Environment.NewLine, Environment.NewLine);
82 | }
83 | else
84 | {
85 | string fmtSpentOn = "";
86 | if (CurTimeEntry.SpentOn.HasValue)
87 | fmtSpentOn = CurTimeEntry.SpentOn.Value.ToString("d", Lang.Culture);
88 | this.Text = String.Format(Lang.DlgTimeEntryFormTitle_Edit, fmtSpentOn, issue.Id, issue.Subject);
89 | labelTimeEntryTitle.Text = String.Format(Lang.labelTimeEntryTitle_Edit, fmtSpentOn, issue.Id, issue.Subject, Environment.NewLine);
90 | }
91 | }
92 |
93 | private void BtnOKButton_Click(object sender, EventArgs e)
94 | {
95 | CurTimeEntry.SpentOn = datePickerSpentOn.Value;
96 | CurTimeEntry.Issue = new IdentifiableName() { Id = issue.Id };
97 | CurTimeEntry.User = new IdentifiableName() { Id = ((ProjectMember)comboBoxByUser.SelectedItem).Id };
98 | CurTimeEntry.Activity = ((Enumerations.EnumerationItem)comboBoxActivity.SelectedItem).ToIdentifiableName();
99 | CurTimeEntry.Hours = decimal.Parse(textBoxSpentHours.Text, Lang.Culture);
100 | CurTimeEntry.Comments = textBoxComment.Text;
101 | try
102 | {
103 | if (type == eFormType.New)
104 | RedmineClientForm.redmine.CreateObject(CurTimeEntry);
105 | else
106 | RedmineClientForm.redmine.UpdateObject(CurTimeEntry.Id.ToString(), CurTimeEntry);
107 | this.DialogResult = DialogResult.OK;
108 | this.Close();
109 | }
110 | catch (Exception ex)
111 | {
112 | MessageBox.Show(String.Format(Lang.Error_Exception, ex.Message), Lang.Error, MessageBoxButtons.OK, MessageBoxIcon.Stop);
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/Redmine.Client/TimeEntryForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/UpdateIssueNoteForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Redmine.Client
2 | {
3 | partial class UpdateIssueNoteForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.TextBoxDescription = new System.Windows.Forms.TextBox();
32 | this.BtnSaveButton = new System.Windows.Forms.Button();
33 | this.BtnCancelButton = new System.Windows.Forms.Button();
34 | this.labelUpdateIssueNote = new System.Windows.Forms.Label();
35 | this.SuspendLayout();
36 | //
37 | // TextBoxDescription
38 | //
39 | this.TextBoxDescription.AcceptsReturn = true;
40 | this.TextBoxDescription.AcceptsTab = true;
41 | this.TextBoxDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
42 | | System.Windows.Forms.AnchorStyles.Left)
43 | | System.Windows.Forms.AnchorStyles.Right)));
44 | this.TextBoxDescription.Location = new System.Drawing.Point(11, 39);
45 | this.TextBoxDescription.Margin = new System.Windows.Forms.Padding(2);
46 | this.TextBoxDescription.Multiline = true;
47 | this.TextBoxDescription.Name = "TextBoxDescription";
48 | this.TextBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both;
49 | this.TextBoxDescription.Size = new System.Drawing.Size(421, 73);
50 | this.TextBoxDescription.TabIndex = 4;
51 | //
52 | // BtnSaveButton
53 | //
54 | this.BtnSaveButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
55 | this.BtnSaveButton.Location = new System.Drawing.Point(151, 116);
56 | this.BtnSaveButton.Margin = new System.Windows.Forms.Padding(2);
57 | this.BtnSaveButton.Name = "BtnSaveButton";
58 | this.BtnSaveButton.Size = new System.Drawing.Size(68, 24);
59 | this.BtnSaveButton.TabIndex = 26;
60 | this.BtnSaveButton.Text = "Save";
61 | this.BtnSaveButton.UseVisualStyleBackColor = true;
62 | this.BtnSaveButton.Click += new System.EventHandler(this.BtnSaveButton_Click);
63 | //
64 | // BtnCancelButton
65 | //
66 | this.BtnCancelButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
67 | this.BtnCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
68 | this.BtnCancelButton.Location = new System.Drawing.Point(223, 116);
69 | this.BtnCancelButton.Margin = new System.Windows.Forms.Padding(2);
70 | this.BtnCancelButton.Name = "BtnCancelButton";
71 | this.BtnCancelButton.Size = new System.Drawing.Size(68, 24);
72 | this.BtnCancelButton.TabIndex = 27;
73 | this.BtnCancelButton.Text = "Cancel";
74 | this.BtnCancelButton.UseVisualStyleBackColor = true;
75 | //
76 | // labelUpdateIssueNote
77 | //
78 | this.labelUpdateIssueNote.AutoSize = true;
79 | this.labelUpdateIssueNote.Location = new System.Drawing.Point(12, 22);
80 | this.labelUpdateIssueNote.Name = "labelUpdateIssueNote";
81 | this.labelUpdateIssueNote.Size = new System.Drawing.Size(79, 13);
82 | this.labelUpdateIssueNote.TabIndex = 28;
83 | this.labelUpdateIssueNote.Text = "Additional Note";
84 | //
85 | // UpdateIssueNoteForm
86 | //
87 | this.AcceptButton = this.BtnSaveButton;
88 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
89 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
90 | this.CancelButton = this.BtnCancelButton;
91 | this.ClientSize = new System.Drawing.Size(443, 151);
92 | this.Controls.Add(this.labelUpdateIssueNote);
93 | this.Controls.Add(this.BtnSaveButton);
94 | this.Controls.Add(this.BtnCancelButton);
95 | this.Controls.Add(this.TextBoxDescription);
96 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
97 | this.MaximizeBox = false;
98 | this.MinimizeBox = false;
99 | this.Name = "UpdateIssueNoteForm";
100 | this.ShowIcon = false;
101 | this.ShowInTaskbar = false;
102 | this.Text = "UpdateIssueNoteForm";
103 | this.Load += new System.EventHandler(this.UpdateIssueNoteForm_Load);
104 | this.ResumeLayout(false);
105 | this.PerformLayout();
106 |
107 | }
108 |
109 | #endregion
110 |
111 | private System.Windows.Forms.TextBox TextBoxDescription;
112 | private System.Windows.Forms.Button BtnSaveButton;
113 | private System.Windows.Forms.Button BtnCancelButton;
114 | private System.Windows.Forms.Label labelUpdateIssueNote;
115 | }
116 | }
--------------------------------------------------------------------------------
/Redmine.Client/UpdateIssueNoteForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using Redmine.Net.Api.Types;
10 | using Redmine.Client.Languages;
11 |
12 | namespace Redmine.Client
13 | {
14 | public partial class UpdateIssueNoteForm : Form
15 | {
16 | private Issue fromIssue;
17 | private Issue toIssue;
18 | public String Note { get; private set; }
19 |
20 | public UpdateIssueNoteForm(Issue fromIssue, Issue toIssue)
21 | {
22 | this.fromIssue = fromIssue;
23 | this.toIssue = toIssue;
24 | InitializeComponent();
25 |
26 | this.Text = String.Format(Lang.DlgUpdateIssueNoteTitle, toIssue.Id, toIssue.Subject);
27 | LangTools.UpdateControlsForLanguage(this.Controls);
28 | }
29 |
30 | private void AddUpdatedLabel(string fieldName, string labelCaption)
31 | {
32 | if (String.IsNullOrEmpty(labelCaption))
33 | return;
34 | Label newLabel = new Label();
35 | newLabel.AutoSize = true;
36 | newLabel.Location = new System.Drawing.Point(labelUpdateIssueNote.Location.X, labelUpdateIssueNote.Location.Y);
37 | newLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
38 | newLabel.Name = "labelUpdateField_" + fieldName;
39 | newLabel.Size = new System.Drawing.Size(44, 13);
40 | newLabel.TabIndex = 4;
41 | newLabel.Text = labelCaption;
42 | newLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
43 | Controls.Add(newLabel);
44 | if (newLabel.Size.Width > Size.Width - newLabel.Location.X - 10)
45 | this.Size = new Size(newLabel.Location.X + newLabel.Size.Width + 10, this.Size.Height);
46 |
47 | SuspendLayout();
48 | int newLabelHeight = newLabel.Height + 5;
49 | Size = new System.Drawing.Size(Size.Width, Size.Height + newLabelHeight);
50 | MinimumSize = new System.Drawing.Size(MinimumSize.Width, MinimumSize.Height + newLabelHeight);
51 | labelUpdateIssueNote.MoveControl(0, newLabelHeight);
52 | TextBoxDescription.MoveControl(0, newLabelHeight);
53 | BtnSaveButton.MoveControl(0, newLabelHeight);
54 | BtnCancelButton.MoveControl(0, newLabelHeight);
55 | ResumeLayout(false);
56 | }
57 |
58 | private void UpdateIssueNoteForm_Load(object sender, EventArgs e)
59 | {
60 | AddUpdatedLabel("project", LangTools.CreateUpdatedText("project", fromIssue.Project, toIssue.Project));
61 | AddUpdatedLabel("tracker", LangTools.CreateUpdatedText("tracker", fromIssue.Tracker, toIssue.Tracker));
62 | AddUpdatedLabel("subject", LangTools.CreateUpdatedText("subject", fromIssue.Subject, toIssue.Subject));
63 | AddUpdatedLabel("priority", LangTools.CreateUpdatedText("priority", fromIssue.Priority, toIssue.Priority));
64 | AddUpdatedLabel("status", LangTools.CreateUpdatedText("status", fromIssue.Status, toIssue.Status));
65 | AddUpdatedLabel("author", LangTools.CreateUpdatedText("author", fromIssue.Author, toIssue.Author));
66 | AddUpdatedLabel("assignedto", LangTools.CreateUpdatedText("assignedto", fromIssue.AssignedTo, toIssue.AssignedTo));
67 | AddUpdatedLabel("category", LangTools.CreateUpdatedText("category", fromIssue.Category, toIssue.Category));
68 | AddUpdatedLabel("parentissue", LangTools.CreateUpdatedText("parentissue", fromIssue.ParentIssue, toIssue.ParentIssue));
69 | AddUpdatedLabel("fixedversion", LangTools.CreateUpdatedText("fixedversion", fromIssue.FixedVersion, toIssue.FixedVersion));
70 | AddUpdatedLabel("start_date", LangTools.CreateUpdatedText("startdate", fromIssue.StartDate, toIssue.StartDate, "d"));
71 | AddUpdatedLabel("duedate", LangTools.CreateUpdatedText("duedate", fromIssue.DueDate, toIssue.DueDate, "d"));
72 | AddUpdatedLabel("doneratio", LangTools.CreateUpdatedText("doneratio", fromIssue.DoneRatio, toIssue.DoneRatio, "0.0"));
73 | AddUpdatedLabel("estimatedhours", LangTools.CreateUpdatedText("estimatedhours", fromIssue.EstimatedHours, toIssue.EstimatedHours, "0.0"));
74 | //AddUpdatedLabel("createdon", LangTools.CreateUpdatedText("createdon", fromIssue.CreatedOn, toIssue.CreatedOn, "d"));
75 | //AddUpdatedLabel("updatedon", LangTools.CreateUpdatedText("updatedon", fromIssue.UpdatedOn, toIssue.UpdatedOn, "d"));
76 | if (fromIssue.Description != toIssue.Description)
77 | AddUpdatedLabel("description", Lang.UpdatedField_Description);
78 | }
79 |
80 | private void BtnSaveButton_Click(object sender, EventArgs e)
81 | {
82 | Note = TextBoxDescription.Text;
83 | this.DialogResult = DialogResult.OK;
84 | this.Close();
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Redmine.Client/UpdateIssueNoteForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Redmine.Client/Utility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Xml;
5 | using System.Diagnostics;
6 |
7 | namespace Redmine.Client
8 | {
9 |
10 | ///
11 | /// Utility class providing helper functions for the application
12 | ///
13 | internal static class Utility
14 | {
15 | ///
16 | /// URL of the current version XML file
17 | ///
18 | private const string currentVersionXmlUrl = "https://redmine-desktop-client.googlecode.com/svn/tags/releases/latestversion.xml";
19 |
20 | ///
21 | /// checks for updates
22 | ///
23 | /// url for downloading the latest version or empty string
24 | internal static string CheckForUpdate()
25 | {
26 | try
27 | {
28 | XmlDocument doc = new XmlDocument();
29 | doc.Load(new XmlTextReader(currentVersionXmlUrl));
30 | Version latestVersion = new Version(doc.SelectSingleNode("//redmineclient/version").InnerText);
31 | string latestVersionUrl = doc.SelectSingleNode("//redmineclient/url").InnerText;
32 | Version myVersion = new Version(FileVersionInfo.GetVersionInfo(System.Windows.Forms.Application.ExecutablePath).FileVersion);
33 | if (myVersion < latestVersion)
34 | {
35 | return latestVersionUrl;
36 | }
37 | }
38 | catch (Exception) // we do not care about the errors, we will simply try it the next time around
39 | {
40 | }
41 |
42 | return String.Empty;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Redmine.Client/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | my username
12 |
13 |
14 | http://redmine.example.org
15 |
16 |
17 | my password
18 |
19 |
20 | True
21 |
22 |
23 | True
24 |
25 |
26 | True
27 |
28 |
29 | True
30 |
31 |
32 | 0
33 |
34 |
35 | 0
36 |
37 |
38 | 540
39 |
40 |
41 | 460
42 |
43 |
44 | 0
45 |
46 |
47 | 0
48 |
49 |
50 | 0
51 |
52 |
53 | en
54 |
55 |
56 | 3
57 |
58 |
59 | 0
60 |
61 |
62 | False
63 |
64 |
65 | False
66 |
67 |
68 | 0
69 |
70 |
71 | False
72 |
73 |
74 | False
75 |
76 |
77 | 0
78 |
79 |
80 | 0
81 |
82 |
83 | 492
84 |
85 |
86 | 374
87 |
88 |
89 | True
90 |
91 |
92 | None
93 |
94 |
95 | Id
96 |
97 |
98 | False
99 |
100 |
101 | False
102 |
103 |
104 | False
105 |
106 |
107 | False
108 |
109 |
110 | False
111 |
112 |
113 | False
114 |
115 |
116 | False
117 |
118 |
119 | xml
120 |
121 |
122 | True
123 |
124 |
125 | True
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/Redmine.Client/res/aboutclock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Redmine.Client/res/aboutclock.png
--------------------------------------------------------------------------------
/Redmine.Client/res/clock-installer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Redmine.Client/res/clock-installer.png
--------------------------------------------------------------------------------
/Redmine.Client/res/clock-transparant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Redmine.Client/res/clock-transparant.png
--------------------------------------------------------------------------------
/Redmine.Client/res/clock.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Redmine.Client/res/clock.ico
--------------------------------------------------------------------------------
/Redmine.Client/res/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Redmine.Client/res/clock.png
--------------------------------------------------------------------------------
/RedmineClient.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redmine.Client", "Redmine.Client\Redmine.Client.csproj", "{07ABD877-B270-4054-B10E-7AA4DEBD37E0}"
7 | EndProject
8 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "Setup\Setup.wixproj", "{CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}"
9 | ProjectSection(ProjectDependencies) = postProject
10 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0} = {07ABD877-B270-4054-B10E-7AA4DEBD37E0}
11 | EndProjectSection
12 | EndProject
13 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Installer", "Installer\Installer.wixproj", "{DE8A1716-DEA3-4CEA-83E5-D24D94519B45}"
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "redmine-net451-api", "Redmine.Api\redmine-net451-api\redmine-net451-api.csproj", "{4AB94C09-8CFB-41C6-87D1-6B972E7F9307}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Debug|Mixed Platforms = Debug|Mixed Platforms
21 | Debug|x86 = Debug|x86
22 | Release|Any CPU = Release|Any CPU
23 | Release|Mixed Platforms = Release|Mixed Platforms
24 | Release|x86 = Release|x86
25 | EndGlobalSection
26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
27 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
30 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
31 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|x86.ActiveCfg = Debug|Any CPU
32 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Debug|x86.Build.0 = Debug|Any CPU
33 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
36 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
37 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|x86.ActiveCfg = Release|Any CPU
38 | {07ABD877-B270-4054-B10E-7AA4DEBD37E0}.Release|x86.Build.0 = Release|Any CPU
39 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Debug|Any CPU.ActiveCfg = Debug|x86
40 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
41 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Debug|Mixed Platforms.Build.0 = Debug|x86
42 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Debug|x86.ActiveCfg = Debug|x86
43 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Debug|x86.Build.0 = Debug|x86
44 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Release|Any CPU.ActiveCfg = Release|x86
45 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Release|Mixed Platforms.ActiveCfg = Release|x86
46 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Release|Mixed Platforms.Build.0 = Release|x86
47 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Release|x86.ActiveCfg = Release|x86
48 | {CAE8E32C-D717-4ED3-A795-C5D10FDBE64E}.Release|x86.Build.0 = Release|x86
49 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Debug|Any CPU.ActiveCfg = Debug|x86
50 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
51 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Debug|Mixed Platforms.Build.0 = Debug|x86
52 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Debug|x86.ActiveCfg = Debug|x86
53 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Debug|x86.Build.0 = Debug|x86
54 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Release|Any CPU.ActiveCfg = Release|x86
55 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Release|Mixed Platforms.ActiveCfg = Release|x86
56 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Release|Mixed Platforms.Build.0 = Release|x86
57 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Release|x86.ActiveCfg = Release|x86
58 | {DE8A1716-DEA3-4CEA-83E5-D24D94519B45}.Release|x86.Build.0 = Release|x86
59 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
60 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|Any CPU.Build.0 = Debug|Any CPU
61 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
62 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
63 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|x86.ActiveCfg = Debug|Any CPU
64 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Debug|x86.Build.0 = Debug|Any CPU
65 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|Any CPU.ActiveCfg = Release|Any CPU
66 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|Any CPU.Build.0 = Release|Any CPU
67 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
68 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|Mixed Platforms.Build.0 = Release|Any CPU
69 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|x86.ActiveCfg = Release|Any CPU
70 | {4AB94C09-8CFB-41C6-87D1-6B972E7F9307}.Release|x86.Build.0 = Release|Any CPU
71 | EndGlobalSection
72 | GlobalSection(SolutionProperties) = preSolution
73 | HideSolutionNode = FALSE
74 | EndGlobalSection
75 | GlobalSection(SubversionScc) = preSolution
76 | Svn-Managed = True
77 | Manager = AnkhSVN - Subversion Support for Visual Studio
78 | EndGlobalSection
79 | EndGlobal
80 |
--------------------------------------------------------------------------------
/Setup/Banner.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Setup/Banner.bmp
--------------------------------------------------------------------------------
/Setup/Dialog.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheMagician1/redmine-desktop-client/083b23d6247c1d87edd5ed9684dc58fd43f70ed9/Setup/Dialog.bmp
--------------------------------------------------------------------------------
/Setup/License.RedmineClient.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\deff3\adeflang1025
2 | {\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\froman\fprq0\fcharset128 Tahoma;}{\f6\froman\fprq0\fcharset128 Calibri;}{\f7\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f8\fnil\fprq2\fcharset0 Mangal;}{\f9\fnil\fprq0\fcharset128 Mangal;}}
3 | {\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
4 | {\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043 Normal;}
5 | {\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af7\dbch\af8\afs28\loch\f4\fs28 Heading;}
6 | {\s16\sbasedon0\snext16\sl288\slmult1\sb0\sa140 Text Body;}
7 | {\s17\sbasedon16\snext17\sl288\slmult1\sb0\sa140\dbch\af9 List;}
8 | {\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af9\afs24\ai\fs24 Caption;}
9 | {\s19\sbasedon0\snext19\noline\dbch\af9 Index;}
10 | }{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern67241475}}\deftab708
11 | \viewscale100
12 | {\*\pgdsctbl
13 | {\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}}
14 | \formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
15 | \pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
16 | Redmine Desktop Client}
17 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
18 | =========}
19 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
20 |
21 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{{\*\bkmkstart __DdeLink__14_824045980}{\*\bkmkend __DdeLink__14_824045980}\rtlch \ltrch\loch\fs17\lang1033\loch\f5
22 | Desktop tool for reporting time spent on issues in Redmine project management system.}
23 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
24 |
25 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
26 | You can download it, report bugs, get the source or post feature requests on }{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
27 | https://github.com/TheMagician1/redmine-desktop-client}
28 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\*\bkmkstart __DdeLink__14_824045980}{\*\bkmkend __DdeLink__14_824045980}{\*\bkmkstart __DdeLink__14_824045980}{\*\bkmkend __DdeLink__14_824045980}\rtlch \ltrch\loch\fs17\lang1033\loch\f5
29 |
30 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
31 | You are free to use this code as much as you wish, but if you make any improvemens, please share them with the community.}
32 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
33 |
34 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
35 | Icons from the excellent Nuvola theme drawn by David Vignoni.}
36 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
37 |
38 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
39 | Copyright (c) 2009, Pavel Kalian}
40 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
41 | Copyright (c) 2012, Bas van Leeuwen}
42 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
43 | All rights reserved.}
44 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
45 |
46 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
47 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:}
48 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
49 |
50 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\fs17\lang1033\loch\f5
51 | }{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
52 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.}
53 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\fs17\lang1033\loch\f5
54 | }{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
55 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.}
56 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\fs17\lang1033\loch\f5
57 | }{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
58 | * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.}
59 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\rtlch \ltrch\loch\fs17\lang1033\loch\f5
60 |
61 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043{\rtlch \ltrch\loch\fs17\lang1033\loch\f5
62 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.}
63 | \par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af10\langfe2052\dbch\af8\afs24\alang1081\loch\f3\fs24\lang1043\sl276\slmult1\sb0\sa200\rtlch \ltrch\loch
64 |
65 | \par }
--------------------------------------------------------------------------------
/Setup/Setup.wixproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 3.5
7 | {cae8e32c-d717-4ed3-a795-c5d10fdbe64e}
8 | 2.0
9 | RedmineClientSetup
10 | Package
11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
13 | Setup
14 |
15 |
16 | bin\$(Configuration)\
17 | obj\$(Configuration)\
18 | Debug
19 |
20 |
21 | bin\$(Configuration)\
22 | obj\$(Configuration)\
23 |
24 |
25 |
26 |
27 |
28 |
29 | $(WixExtDir)\WixUIExtension.dll
30 | WixUIExtension
31 |
32 |
33 | $(WixExtDir)\WixNetFxExtension.dll
34 | WixNetFxExtension
35 |
36 |
37 |
38 |
39 | redmine-net40-api
40 | {0d9b763c-a16b-463b-bddd-0a0467dcd32e}
41 | True
42 | True
43 | Binaries;Content;Satellites
44 | INSTALLFOLDER
45 |
46 |
47 | Redmine.Client
48 | {07abd877-b270-4054-b10e-7aa4debd37e0}
49 | True
50 | True
51 | Binaries;Content;Satellites
52 | INSTALLFOLDER
53 |
54 |
55 |
56 |
66 |
67 |
68 |
--------------------------------------------------------------------------------