From e1ae47aee94266cb79e99298f5bc0c3db5bd2ab2 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Sun, 7 Aug 2022 13:38:40 +0300 Subject: [PATCH] =?UTF-8?q?TeacherControlPlugin=20-=20=D0=B2=D1=8B=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=85?= =?UTF-8?q?=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- Localization/DefaultLang.resources | Bin 100784 -> 100748 bytes PluginsSupport/Classes.cs | 3 + PluginsSupport/Interfaces.cs | 7 + PluginsSupportLinux/Classes.cs | 3 + PluginsSupportLinux/Interfaces.cs | 7 + Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- TestSuite/CompilationSamples/PT4.pas | 10 +- .../SyntaxTreeVisitorNodes/Foreach.cs | 1 + .../DS/PluginsController/PluginsController.cs | 4 +- .../DS/PluginsController/PluginsController.cs | 2 + .../TraningControlPlugin/IconAuthorized.bmp | Bin 0 -> 4150 bytes .../TraningControlPlugin/IconAuthorized.ico | Bin 0 -> 5430 bytes .../TraningControlPlugin/IconAuthorized.png | Bin 0 -> 1102 bytes .../TraningControlPlugin/IconAuthorized1.ico | Bin 0 -> 5430 bytes .../LoginForm.Designer.cs | 214 +++++++++++ .../TraningControlPlugin/LoginForm.cs | 111 ++++++ .../TraningControlPlugin/LoginForm.resx | 347 ++++++++++++++++++ .../Properties/Resources.Designer.cs | 14 +- .../Properties/Resources.resx | 8 +- .../TraningControlPlugin/SiteAccessInfo.cs | 207 +++++++++++ .../TeacherControlPlugin.cs | 83 +++-- .../TeacherControlPlugin.csproj | 26 +- bin/Lib/LightPT.pas | 55 ++- bin/Lib/PT4.pas | 10 +- 27 files changed, 1059 insertions(+), 61 deletions(-) create mode 100644 VisualPlugins/TraningControlPlugin/IconAuthorized.bmp create mode 100644 VisualPlugins/TraningControlPlugin/IconAuthorized.ico create mode 100644 VisualPlugins/TraningControlPlugin/IconAuthorized.png create mode 100644 VisualPlugins/TraningControlPlugin/IconAuthorized1.ico create mode 100644 VisualPlugins/TraningControlPlugin/LoginForm.Designer.cs create mode 100644 VisualPlugins/TraningControlPlugin/LoginForm.cs create mode 100644 VisualPlugins/TraningControlPlugin/LoginForm.resx create mode 100644 VisualPlugins/TraningControlPlugin/SiteAccessInfo.cs diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 6a82daa57..64f88b553 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "8"; public const string Build = "3"; - public const string Revision = "3150"; + public const string Revision = "3152"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index dd4605542..57938be3a 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=3 -%REVISION%=3150 +%REVISION%=3152 %MINOR%=8 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index be043f15947b2881477b2b8b04f900556837f80e..d04cd7526a243b735ab0ed4ec004cbcd08415dcc 100644 GIT binary patch delta 76 zcmdlmnXP9s+k^*goq_ES0V=+nCoFP=a6_ToP;my2t#bC731h^N1wEt14!M}IkP PBz|+Q|MpyeMrSJkkb*3= delta 112 zcmeB~%(h`N+k^*Ejn4KYe)d;oYMLZ{Pm@s__2Z z>p#zdoKH_*KYhu|<>DIb9OM}g;_2^ad-}!qx4&O1yn68P#oMQ!CM)>M@u3Ped-`wp J^k;Oo0sy6oNvr?> diff --git a/PluginsSupport/Classes.cs b/PluginsSupport/Classes.cs index ac032ccc4..7c939977a 100644 --- a/PluginsSupport/Classes.cs +++ b/PluginsSupport/Classes.cs @@ -17,6 +17,9 @@ namespace VisualPascalABCPlugins System.Windows.Forms.Keys shortcutKeys = System.Windows.Forms.Keys.None; string shortcutKeyDisplayString = null; + public object menuItem { get; set; } + public object toolStripButton { get; set; } + public PluginGUIItem(string text, string hint, Image image, Color imageTransparentColor, PluginGUIItemExecuteDelegate executeDelegate) { this.text = text; diff --git a/PluginsSupport/Interfaces.cs b/PluginsSupport/Interfaces.cs index a1d7f4346..3f78832ad 100644 --- a/PluginsSupport/Interfaces.cs +++ b/PluginsSupport/Interfaces.cs @@ -32,6 +32,13 @@ namespace VisualPascalABCPlugins { get; } + + /// SSM 07.08.22 . ToolStripMenuItem + object menuItem { get; set; } + + /// SSM 07.08.22 . ToolStripButton + object toolStripButton { get; set; } + void Execute(); } diff --git a/PluginsSupportLinux/Classes.cs b/PluginsSupportLinux/Classes.cs index ac032ccc4..7c939977a 100644 --- a/PluginsSupportLinux/Classes.cs +++ b/PluginsSupportLinux/Classes.cs @@ -17,6 +17,9 @@ namespace VisualPascalABCPlugins System.Windows.Forms.Keys shortcutKeys = System.Windows.Forms.Keys.None; string shortcutKeyDisplayString = null; + public object menuItem { get; set; } + public object toolStripButton { get; set; } + public PluginGUIItem(string text, string hint, Image image, Color imageTransparentColor, PluginGUIItemExecuteDelegate executeDelegate) { this.text = text; diff --git a/PluginsSupportLinux/Interfaces.cs b/PluginsSupportLinux/Interfaces.cs index fcd5471a3..ca9e08a1f 100644 --- a/PluginsSupportLinux/Interfaces.cs +++ b/PluginsSupportLinux/Interfaces.cs @@ -32,6 +32,13 @@ namespace VisualPascalABCPlugins { get; } + + /// SSM 07.08.22 . ToolStripMenuItem + object menuItem { get; set; } + + /// SSM 07.08.22 . ToolStripButton + object toolStripButton { get; set; } + void Execute(); } diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 3dcef80cc..9643a6e59 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.8.3.3150 +3.8.3.3152 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 008c714bf..552d23456 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.8.3.3150' +!define VERSION '3.8.3.3152' diff --git a/TestSuite/CompilationSamples/PT4.pas b/TestSuite/CompilationSamples/PT4.pas index aa9e5aef9..d008361d7 100644 --- a/TestSuite/CompilationSamples/PT4.pas +++ b/TestSuite/CompilationSamples/PT4.pas @@ -81,6 +81,8 @@ type property Parent: Node read getParent write SetParent; property Data: integer read getData write SetData; end; + +var TaskName: string; /// Вывести формулировку задания procedure Task(name: string); @@ -833,7 +835,7 @@ procedure StartPT(options: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' procedure FreePT; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'freept'; function CheckPT(var res: integer):string;external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'checkptf'; procedure RaisePT(s1,s2: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'raisept'; -procedure Task(name: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'task'; +procedure Task__(name: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'task'; procedure GetR(var param: real); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getr'; procedure PutR(param: real); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putr'; procedure GetN(var param: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getn'; @@ -850,6 +852,12 @@ procedure DisposeP(sNode: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' function FinishPT(): integer; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'finishpt'; // == 4.13 == procedure _GetSolutionInfo(info: System.Text.StringBuilder);external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getsolutioninfo'; +procedure Task(name: string); +begin + Task__(name); + TaskName := name; +end; + procedure Dispose(p: pointer); begin DisposeP(IntPtr(p)); diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs index 9933b20fe..3a8993d53 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs @@ -48,6 +48,7 @@ namespace PascalABCCompiler.TreeConverter } // SSM 29.07.16 - если in_what - одномерный массив, то заменить код foreach на for + // Лямбды обходят старое дерево, поэтому не работает. Кстати, почему? SSM 04/08/22 // if (OptimizeForeachInCase1DArray(_foreach_stmt, foreachCollection)) return; statements_list sl = new statements_list(get_location(_foreach_stmt.stmt)); diff --git a/VisualPascalABCNET/DS/PluginsController/PluginsController.cs b/VisualPascalABCNET/DS/PluginsController/PluginsController.cs index 43b2c083a..ba73ea08c 100644 --- a/VisualPascalABCNET/DS/PluginsController/PluginsController.cs +++ b/VisualPascalABCNET/DS/PluginsController/PluginsController.cs @@ -76,8 +76,9 @@ namespace VisualPascalABCPlugins menuItem.Image = Item.Image; menuItem.ImageTransparentColor = Item.ImageTransparentColor; menuItem.Text = Item.Text; - menuItem.ToolTipText = Item.Hint; + //menuItem.ToolTipText = Item.Hint; menuItem.Tag = Item; + Item.menuItem = menuItem; menuItem.ShortcutKeys = Item.ShortcutKeys; if (Item.ShortcutKeyDisplayString != null) menuItem.ShortcutKeyDisplayString = Item.ShortcutKeyDisplayString; @@ -110,6 +111,7 @@ namespace VisualPascalABCPlugins button.ToolTipText = Item.Hint; button.Click += new EventHandler(button_Click); button.Tag = Item; + Item.toolStripButton = button; ToolStrip.Items.Add(button); PascalABCCompiler.StringResources.SetTextForObject(button, ""); } diff --git a/VisualPascalABCNETLinux/DS/PluginsController/PluginsController.cs b/VisualPascalABCNETLinux/DS/PluginsController/PluginsController.cs index 8634468bf..c9b00803c 100644 --- a/VisualPascalABCNETLinux/DS/PluginsController/PluginsController.cs +++ b/VisualPascalABCNETLinux/DS/PluginsController/PluginsController.cs @@ -78,6 +78,7 @@ namespace VisualPascalABCPlugins menuItem.Text = Item.Text; //menuItem.ToolTipText = Item.Hint; menuItem.Tag = Item; + Item.menuItem = menuItem; menuItem.ShortcutKeys = Item.ShortcutKeys; if (Item.ShortcutKeyDisplayString != null) menuItem.ShortcutKeyDisplayString = Item.ShortcutKeyDisplayString; @@ -110,6 +111,7 @@ namespace VisualPascalABCPlugins button.ToolTipText = Item.Hint; button.Click += new EventHandler(button_Click); button.Tag = Item; + Item.toolStripButton = button; ToolStrip.Items.Add(button); PascalABCCompiler.StringResources.SetTextForObject(button, ""); } diff --git a/VisualPlugins/TraningControlPlugin/IconAuthorized.bmp b/VisualPlugins/TraningControlPlugin/IconAuthorized.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3224b8cb8fd3342b12d534ebd5e0ecfbd3bce9f0 GIT binary patch literal 4150 zcmb`K%a2S!6voFtAhThE#74pv5sOJWx9WBq5jIv57Q`bKWOhgh30o^+Lp&B=2fBCtm#*AS@@C?%T1sf$EChta?rc1*)czxxXd#lTh7`$uY|BQ{(evIDs zkjGlPmHr2ek1_T%oI{{L5MuJQ;q0z*UkY((o{HjgE{{4Ci^Z9$L$ms1|+Xj0X4V|4yH7DMO={)ZXx!hjpJXqT) z{r0xD8E8LY{$InqdfVXozz_L+^t5hicVp6*SNyjQXnz6I>(61DBwE97{2I?wuZK(b z#hqR4H$1iO@r1_3i+_W?^!i|SVdL2GdUbss>v#s&-`c^EfBk8?7~Chn4$obWNB;`g zQJW;&!hHHv^UVGCHGt5IA|A*)dv)AtYd;L<9ETVq^ z`@!Al2)VM_Xx|1m##}Cjxy14PKVQwe;dMjLoHjB34I64;4ll&5I_Qpt^WfQE^Z6I* zt4$qtR_E{|+za}4u%2%E`em+7pVuM2Ro!pxx$gI8`t)9y^7$X@D@JQ0_6pOTcn8mO z$7#$6{-cbs5ll7L*gNH-Da=89C)Uf@OX6M^NBjLR-MA0@9k?s&F{X$8S?AZQc6D6O zKFzr&#y1V@pA`!utT^)O`h4(vuyVcj!mF{IOflaIWtFu6-QoOpU=CZo%;R6db0H5abbiNhv&=d+Y5!+aP(r| zbrxfdTCs8+Cit$)tL^jomeIF^-eGrZ>BarZ6-HRk)2KJb%!2PG>(MjyTC5ev%2BQ` zjcUfYWyUOo*ZpRKx4)Pq2V&jodDnAS&%OK1dtuDeOw67xu)I^?*Ei9)^OfJIgVna{ hL;JLHo6(vItMiP;QR?v=-C>z)TYC(@d@5|#*dLAe9*+P3 literal 0 HcmV?d00001 diff --git a/VisualPlugins/TraningControlPlugin/IconAuthorized.ico b/VisualPlugins/TraningControlPlugin/IconAuthorized.ico new file mode 100644 index 0000000000000000000000000000000000000000..8ac1eeb9b802e37b77d43ef9db82f0baf85ae330 GIT binary patch literal 5430 zcmb`LZ)jCz9LLYLz@TUbnM7rSDC$j+^`aNT-F?p8-5p!LD1?%FVU#A7_$FMi+9gAJ zQyFU&DE%R=~DP!I%kT6r2%s z$B=Qx75u&^6bko{L%qwx@ypkIcYpO_1l)(fKZ;D!-vi&OI8GRbE79-9K7sAmC`g^g?wIfI7|DW!^zr$rSoFYy_g z&x5-^_5O4GYPAm3p)<=!PV=kIwNh{wi8;t+~$kQFMAPB;EgYao%`8 z+6#}u_XnagaTuKa7Sot9+P@{(#t_w9w!`v;Q!y{mZbb&M9bi0Y$E>%zbK`tTeY+Mq z6UOWUdul$$46r^AyZNdg*>(3-;Th05Qmp2nyM^%rcgH00Tu4XU9pLW;`z*4-@%pW7 z)(2n3TnIC(jr^|!^L^%|{q&*F>5t_jU-I3g*sMHhe(c|N@J^D$kk6Gimak$In}(Z3 zZ}(pqeqiTrOm`ZeugAYzF{+y|vT!B&uxD-o;~=#>;&ap*!~d6Jg^`4vMMvynFwU^1 zJ8JRycH(x}*nEC*7Oo^8=CB$JJwtnZ{90qhC{`Fr*jaSMKZ{h0#;mQy=i7^g!dk@& zBMVoO53#F|bMW{2__fCDnb#F7j3n$VI-V6J>h~`)P>avED@L)x$ikK6Q_AIT0Amn2 zrM>8Lq>bfkV~7<-5_T3{cXxL^?=pIK&@=3tG(KN1U&Sa^7+JW|e7MK22X80y(VhC4 z&*hKhBVWZRHVt<+`c`8Wf@{B-z#VGI=U?!7qy4UXSNGoca4(zg)c1-ST&ZR~&$OT6*g!q@!&{Nqei&|~ZM(#0UL)iUktqN3 z=1@k7)b&qE!$JH{1VLkkSGI|uv04e{SUC|iRBMTR6(gwzxvKuB(BBeGi2I+Sng1~S zANB2Iu1DAlzajh1lc{%S)#enU_psg6?8Q<(f3u)@F6(<>y}yUtnD?np*7{qG;aQ;; zT`xGj?5p{-&q| z=H?u>t$v&vWBWMP-x=$_Ne)l6x3^yn&THHcGrotX{fv2@8olAhYLz#!+w^Us8kWNF zPHMDSwUnK9DY>q(E#I#6e?s&%yN!7)EtN`hw4Qo5)fp8=(|lIaSe6cz}bH}o~y>v<3CS4DR*EU9QVSP_)aOk?9iNd2E=XO z&5T)xUuT@#^`&QC>(bu8$n7fTsWbb4i;1_=%Pv3h`9HoNuAnYG_}Tp#k5ylKYsb%z z)mU{Q$7OK5=f`R+z3lQ!ikGgnwe>pItVgwmuPx$jvt#tKr^QBk-Kz`8vy1p$)aw_u b#CJ)LPh#yagjpt{pB+}_CiA8LCTz%m!3x?F literal 0 HcmV?d00001 diff --git a/VisualPlugins/TraningControlPlugin/IconAuthorized.png b/VisualPlugins/TraningControlPlugin/IconAuthorized.png new file mode 100644 index 0000000000000000000000000000000000000000..903c6e52aea9aee1aec8660b25ccf0030fc47c25 GIT binary patch literal 1102 zcmV-U1hM;xP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1LH|VK~z{rt(Q$m z6;T+5wKgqUv?&*sv}w_%g}G=UT<-j72yVhfP>Z4;TqN!)Pz-F_Dr#d?F0`U@QBWk( z4;l1>5=e!lnb{wyi^9k>tLMFQM(5s+w>#9l`x*JI~T9G(}nB0d!Q_)i?iDL3KEGl)tNy(?mpxScDU3;CEtiE&B| z&C;x;rDat*?KUx^SqLB51Z|M7ViYS5LzmoAsp^f)W&nKSxz^gmY>=;F6e|uxm)unG zkbDQdHlch_jAF%M=#m@D*Z_VzPH@I1k`L6vS;dOO&?Ps5n*n4&t4$;y%v(V{_|1kc zxv_+e5NH;sZ6f)g7{!Xi&?Pq&6C^*V>Ta7zJ`mTf*mT;fHFU|11hzo(mgo7wCXx@# z{G(#UVd#<@`}!JYe+e=+A+N>U7az#Qc75#r+`lf+NjPlB$2 zmR_F<@4;L*RSspavlQ=d;f9Fc4Bar*5!{VT?=C+l&T=YA3BInFP8A%N^K zv!XVdstF^X*?uc<{0zxh+_?}yc9U3r2_1=#Gj;-G+U#++ zUjArxMQ=wj1IK|X{(RiI5RkwtW;GG@;n2(_PQhjpP^oK+QDtTIda`*QpG6W7#}4RCMty{mtw0b2 zn;6hR@-A{n0%Em#+6^1B#|x~1RH|w-9WCQX+_6wVc!*ebMZZ6Le9^Z+`@uBJAHD_4 zO+Y|IyP`Ik>+x~Ka`%DD@}phY2Vw~%egz{yxCdgkUi~Zj{Unm}INZf|!i5Af&rv^~ znbk-F$hGJ59T`@9I7@Gmd+=G$f`vaP3Sk|NcW_$l^;s4Woq+!q=fVDePs5_3zeZk07*qoM6N<$f(~#1_W%F@ literal 0 HcmV?d00001 diff --git a/VisualPlugins/TraningControlPlugin/IconAuthorized1.ico b/VisualPlugins/TraningControlPlugin/IconAuthorized1.ico new file mode 100644 index 0000000000000000000000000000000000000000..06be29936b009ee0509a8a8e6567e2c7314df895 GIT binary patch literal 5430 zcmchbU1%It6vro3P!KeNRm87=DEesi!H2?T?#ymBB=$iGXwip?widPYMH(TRU`2dU zD={jh_<>Xtw6RoBEVV|OqE@Uzw6&NTYg(1Id1$FLX+GB9e=;}Rz1_`bH)7!A-t+N4 z|8vj1GdnXuP!}u<8X5w|hM=!L2yP96pq^3sV;2X(0p_=1BP3`SC&y zlXEc5z1_vZ`L3t;C2{m2o6TOWJ}i}=wXLOhlUjEXR}^(nm(Em2k$tWY6ZBw>_;b13 z4d6$p>kl_>v2(CH;n3MB>N$EBqVwG4=1TTL=OKy)#GhZeayi^TQvWG8Zn1N42f>fq zc=)t#aStNm*C>6y4{)CZGi=Xc9EMuMdBz89p2d#j()E&@UF|n{%3a5^@+&XnQRIl_ z2lF&CgS@p^UK__c4v}lVcjTyk{c(I3xWDZ>Z0^O3@P7h!Dhk6V-FR&3dBy#=Js{6J z$P6{S?dGX8XYK3YnFRN}8;h;n`Tq`{3HCZU|CT=&hIe8gMb2_7($7XrZzfAXAd#>yI1UCIHEO`I-`K8142=W`EYvLGr4ktN{nPmJ+f^QO0&*eL& zSU81wiE#iK#&-mLIMKcRF2(EH!0#pZ+(xB<>)xlDhkX1}b@Cr1_j#n( z^7^BENer<|<#X}me4jPxJbmbM`nqBiOTF9N9JS6lzb)iDO${SHS2E&^sqmmB)pTgF{YccSzBF8y;u&WZE?+3Rl z!G_@~o3GlDHEbk@enY$c{FQWJgjJ4ed2KxSXOKe9n9Y^=e19&EHw&vAHeaR38YY;bQ=>{7TE z!sWj#MVQe9?sP@jL%AJ zyg%Zbf7Yh9t=3PjermrL{}Y_ySFGJ1!R(YxSYk)m^Dh$Jm{(O>+}N1GH{j!}j_+e< zzQ>urNez#;w6t7Fp4YfP6ul46#~Je+J$l3H8dW#g9eOuW5A#uU2R-UnFXd-kO|6@f zk#|?-KOlM^+d@6!-N8Cm=kxhXw4ZHlZ5QbpRgN^aPkTgNeZ=b>d^_=L$@dg>uGc-l zVujaVYisLO^s$#~|7EvU>9P~QTs)nfoy+DBMgQyIxCg$H&y=#u52CIJl`4EIyOg?L zAg + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LoginForm)); + this.groupNamesBox = new System.Windows.Forms.ComboBox(); + this.usersNamesBox = new System.Windows.Forms.ComboBox(); + this.labelGroup = new System.Windows.Forms.Label(); + this.labelUser = new System.Windows.Forms.Label(); + this.passwordBox = new System.Windows.Forms.TextBox(); + this.labelPassword = new System.Windows.Forms.Label(); + this.enterButton = new System.Windows.Forms.Button(); + this.closeButton = new System.Windows.Forms.Button(); + this.userImage = new System.Windows.Forms.PictureBox(); + this.groupImage = new System.Windows.Forms.PictureBox(); + this.PluginImage = new System.Windows.Forms.PictureBox(); + this.PluginImageAuthorized = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.userImage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.groupImage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PluginImage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PluginImageAuthorized)).BeginInit(); + this.SuspendLayout(); + // + // groupNamesBox + // + this.groupNamesBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.groupNamesBox.FormattingEnabled = true; + this.groupNamesBox.Location = new System.Drawing.Point(114, 12); + this.groupNamesBox.Name = "groupNamesBox"; + this.groupNamesBox.Size = new System.Drawing.Size(258, 21); + this.groupNamesBox.TabIndex = 1; + this.groupNamesBox.SelectedIndexChanged += new System.EventHandler(this.GroupNamesBox_SelectedIndexChanged); + // + // usersNamesBox + // + this.usersNamesBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.usersNamesBox.FormattingEnabled = true; + this.usersNamesBox.Location = new System.Drawing.Point(114, 50); + this.usersNamesBox.Name = "usersNamesBox"; + this.usersNamesBox.Size = new System.Drawing.Size(258, 21); + this.usersNamesBox.TabIndex = 2; + // + // labelGroup + // + this.labelGroup.AutoSize = true; + this.labelGroup.Location = new System.Drawing.Point(63, 15); + this.labelGroup.Name = "labelGroup"; + this.labelGroup.Size = new System.Drawing.Size(45, 13); + this.labelGroup.TabIndex = 3; + this.labelGroup.Text = "Группа:"; + // + // labelUser + // + this.labelUser.AutoSize = true; + this.labelUser.Location = new System.Drawing.Point(25, 53); + this.labelUser.Name = "labelUser"; + this.labelUser.Size = new System.Drawing.Size(83, 13); + this.labelUser.TabIndex = 4; + this.labelUser.Text = "Пользователь:"; + // + // passwordBox + // + this.passwordBox.Location = new System.Drawing.Point(114, 92); + this.passwordBox.Name = "passwordBox"; + this.passwordBox.Size = new System.Drawing.Size(258, 20); + this.passwordBox.TabIndex = 5; + // + // labelPassword + // + this.labelPassword.AutoSize = true; + this.labelPassword.Location = new System.Drawing.Point(60, 95); + this.labelPassword.Name = "labelPassword"; + this.labelPassword.Size = new System.Drawing.Size(48, 13); + this.labelPassword.TabIndex = 6; + this.labelPassword.Text = "Пароль:"; + // + // enterButton + // + this.enterButton.Location = new System.Drawing.Point(87, 131); + this.enterButton.Name = "enterButton"; + this.enterButton.Size = new System.Drawing.Size(118, 34); + this.enterButton.TabIndex = 8; + this.enterButton.Text = "Вход"; + this.enterButton.UseVisualStyleBackColor = true; + this.enterButton.Click += new System.EventHandler(this.enterButton_Click); + // + // closeButton + // + this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.closeButton.Location = new System.Drawing.Point(225, 131); + this.closeButton.Name = "closeButton"; + this.closeButton.Size = new System.Drawing.Size(118, 34); + this.closeButton.TabIndex = 7; + this.closeButton.Text = "Закрыть"; + this.closeButton.UseVisualStyleBackColor = true; + this.closeButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // userImage + // + this.userImage.InitialImage = null; + this.userImage.Location = new System.Drawing.Point(378, 45); + this.userImage.Name = "userImage"; + this.userImage.Size = new System.Drawing.Size(32, 32); + this.userImage.TabIndex = 10; + this.userImage.TabStop = false; + // + // groupImage + // + this.groupImage.InitialImage = null; + this.groupImage.Location = new System.Drawing.Point(378, 7); + this.groupImage.Name = "groupImage"; + this.groupImage.Size = new System.Drawing.Size(32, 32); + this.groupImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.groupImage.TabIndex = 9; + this.groupImage.TabStop = false; + // + // PluginImage + // + this.PluginImage.BackColor = System.Drawing.Color.Magenta; + this.PluginImage.Image = ((System.Drawing.Image)(resources.GetObject("PluginImage.Image"))); + this.PluginImage.Location = new System.Drawing.Point(379, 95); + this.PluginImage.Margin = new System.Windows.Forms.Padding(6); + this.PluginImage.Name = "PluginImage"; + this.PluginImage.Size = new System.Drawing.Size(25, 26); + this.PluginImage.TabIndex = 11; + this.PluginImage.TabStop = false; + this.PluginImage.Visible = false; + // + // PluginImageAuthorized + // + this.PluginImageAuthorized.BackColor = System.Drawing.Color.Magenta; + this.PluginImageAuthorized.Image = ((System.Drawing.Image)(resources.GetObject("PluginImageAuthorized.Image"))); + this.PluginImageAuthorized.InitialImage = null; + this.PluginImageAuthorized.Location = new System.Drawing.Point(379, 131); + this.PluginImageAuthorized.Name = "PluginImageAuthorized"; + this.PluginImageAuthorized.Size = new System.Drawing.Size(25, 26); + this.PluginImageAuthorized.TabIndex = 12; + this.PluginImageAuthorized.TabStop = false; + this.PluginImageAuthorized.Visible = false; + // + // LoginForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.closeButton; + this.ClientSize = new System.Drawing.Size(422, 175); + this.Controls.Add(this.PluginImageAuthorized); + this.Controls.Add(this.PluginImage); + this.Controls.Add(this.userImage); + this.Controls.Add(this.groupImage); + this.Controls.Add(this.closeButton); + this.Controls.Add(this.enterButton); + this.Controls.Add(this.labelPassword); + this.Controls.Add(this.passwordBox); + this.Controls.Add(this.labelUser); + this.Controls.Add(this.labelGroup); + this.Controls.Add(this.usersNamesBox); + this.Controls.Add(this.groupNamesBox); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "LoginForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Авторизация"; + this.Load += new System.EventHandler(this.LoginForm_Load); + ((System.ComponentModel.ISupportInitialize)(this.userImage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.groupImage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PluginImage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PluginImageAuthorized)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ComboBox groupNamesBox; + private System.Windows.Forms.ComboBox usersNamesBox; + private System.Windows.Forms.Label labelGroup; + private System.Windows.Forms.Label labelUser; + private System.Windows.Forms.TextBox passwordBox; + private System.Windows.Forms.Label labelPassword; + private System.Windows.Forms.Button enterButton; + private System.Windows.Forms.Button closeButton; + private System.Windows.Forms.PictureBox groupImage; + private System.Windows.Forms.PictureBox userImage; + public System.Windows.Forms.PictureBox PluginImage; + public System.Windows.Forms.PictureBox PluginImageAuthorized; + } +} \ No newline at end of file diff --git a/VisualPlugins/TraningControlPlugin/LoginForm.cs b/VisualPlugins/TraningControlPlugin/LoginForm.cs new file mode 100644 index 000000000..d8aa0b066 --- /dev/null +++ b/VisualPlugins/TraningControlPlugin/LoginForm.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using VisualPascalABCPlugins; + +namespace DBAccessPluginNamespace +{ + public partial class LoginForm : Form + { + public SiteAccessProvider SiteProvider = null; + public VisualPascalABCPlugin_TeacherControlPlugin Plugin = null; + + public LoginForm(VisualPascalABCPlugin_TeacherControlPlugin Plugin) + { + this.Plugin = Plugin; + InitializeComponent(); + } + + public bool Authorized = false; + private async void enterButton_Click(object sender, EventArgs e) + { + if (SiteProvider == null) + throw new Exception("Error in Login form! Site credentials cannot be empty!"); + + if (!Authorized) + { + var answer = await SiteProvider.Login("", usersNamesBox.Text, passwordBox.Text); + if(answer == "Success") + { + //DialogResult = DialogResult.OK; + //Close(); + Text = "Авторизация: вход выполнен"; + passwordBox.Text = ""; + enterButton.Text = "Выход"; + passwordBox.Visible = false; + labelPassword.Visible = false; + groupNamesBox.Enabled = false; + usersNamesBox.Enabled = false; + Authorized = true; + Plugin.toolStripButton.ToolTipText = "Авторизация выполнена: " + SiteProvider.FullFIO; + Plugin.toolStripButton.Image = PluginImageAuthorized.Image; + Plugin.menuItem.Image = PluginImageAuthorized.Image; + this.Icon = VisualPascalABCPlugins.Properties.Resources.IconAuthorized; + closeButton.Focus(); + } + else MessageBox.Show(answer,"Ошибка"); + } + else + { + SiteProvider.Logout(); + Text = "Авторизация"; + passwordBox.Text = ""; + enterButton.Text = "Вход"; + groupNamesBox.SelectedIndex = -1; + usersNamesBox.Items.Clear(); + usersNamesBox.SelectedIndex = -1; + groupNamesBox.Enabled = true; + usersNamesBox.Enabled = true; + passwordBox.Visible = true; + labelPassword.Visible = true; + Authorized = false; + Plugin.toolStripButton.ToolTipText = "Авторизация: вход не выполнен"; + Plugin.toolStripButton.Image = PluginImage.Image; + Plugin.menuItem.Image = PluginImage.Image; + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LoginForm)); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + } + + } + + private async void LoginForm_Load(object sender, EventArgs e) + { + // Получить список групп и заполнить выпадающий список значениями + if (SiteProvider == null) + throw new Exception("Error in Login form! Site credentials cannot be empty!"); + if (groupNamesBox.Items.Count > 0) // Группы уже загружены + return; + //groupImage.Image = Properties.Resources.LoadingImg; + var groups = await SiteProvider.GetGroupsNames(); + groupNamesBox.Items.Clear(); + groupNamesBox.Items.AddRange(groups.Split(';').Where(Item => Item != "").ToArray()); + //groupImage.Image = null; + } + + private async void GroupNamesBox_SelectedIndexChanged(object sender, EventArgs e) + { + // Получить список участников группы + if (groupNamesBox.Text == "") return; + + if (SiteProvider == null) + throw new Exception("Error in Login form! Site credentials cannot be empty!"); + //userImage.Image = Properties.Resources.LoadingImg; + var users = await SiteProvider.GetUsersNames(groupNamesBox.Text); + usersNamesBox.Items.Clear(); + usersNamesBox.Items.AddRange(users.Split(';').Where(Item => Item != "").ToArray()); + //userImage.Image = null; + } + + private void cancelButton_Click(object sender, EventArgs e) + { + Close(); + passwordBox.Text = ""; + } + } +} diff --git a/VisualPlugins/TraningControlPlugin/LoginForm.resx b/VisualPlugins/TraningControlPlugin/LoginForm.resx new file mode 100644 index 000000000..80d76e2ef --- /dev/null +++ b/VisualPlugins/TraningControlPlugin/LoginForm.resx @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + Qk02DAAAAAAAADYAAAAoAAAAIAAAACAAAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wD/d3Z2 + RUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUNDRUND + RUNDRUNDUlBQeXh4/wD//wD//wD//wD//wD//wD//wD/W1paR0VFWVdXW1paW1paW1paW1paW1paW1pa + W1paW1paW1paW1paW1paW1paW1paWlhYSkhIRUNDRUNDRkREUU9PWFdXU1FRR0VFSUdHdXNz/wD//wD/ + /wD//wD//wD/W1paWFdX09HR5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bm5+bmu7q6 + U1FRRUNDaGZmrq2t19fX4ODg2tnZsbGxa2lpRkREY2Fh/wD//wD//wD//wD/W1paW1pa5+bm//////// + ////////////////////////////////////////7OzscnFxRkREgH9/5OTk/v7+1dXViYeH1dXV/v7+ + 5+bmhIKCRkREdXNz/wD//wD//wD/W1paW1pa5+bm//////////////////////////////////////// + ////////s7OzSEdHaGZm5eTk////////pKOjRUNDpKOj////////5+fna2lpSUdH/wD//wD//wD/XVxc + WVdX5OPj////////////////////////////////////////////9/f3fHt7R0VFrq2t/v7+//////// + oaCgRUNDoaCg/////////v7+sbGxR0VFf35+/wD//wD/ZmRkUlBQ2tnZ//////////////////////// + ////////////////////7OzsYmBgUU9P19fX1dXVpKOjoaCgcnFxRUNDcnFxoaCgpKOj1dXV2dnZUlFR + ZGJi/wD//wD/fHp6SEZGvby8////////////////////////////////////////////5+bmW1paWFdX + 4ODgiYeHRUNDRUNDRUNDRUNDRUNDRUNDRUNDiYeH4uLiWlhYXVtb/wD//wD/pqWlRkREi4qK+/n5//// + ////////////////////////////////////6+vrYV9fUlBQ2NjY1dXVpKOjoaCgcnFxRUNDcnFxoaCg + pKOj1dXV2dnZUlFRZGJi/wD//wD//wD/VVNTWFdX2tra//////////////////////////////////// + ////9/f3e3p6R0VFrq2t/v7+////////oaCgRUNDoaCg/////////v7+sbGxR0VFf35+/wD//wD//wD/ + iYiIRUNDiomJ9fX1////////////////////////////////////////s7KySUdHaGdn5eXl//////// + pKOjRUNDpKOj////////5+bmamhoSUdH/wD//wD//wD//wD//wD/W1lZTEpKrKys+/v7//////////// + ////////////////////////7ezscXBwRkREgX9/5eXl/v7+1dXViYeH1dXV/v7+5+bmg4GBRkREdXNz + /wD//wD//wD//wD//wD/tLOzTkxMUU9PrKys9fX1/////////v7+9PT06enp6enp9PT0/v7+/v7+0tHR + Xl1dRkREaGdnsbGx2tra4uHh2trasrGxa2lpRkREY2Fh/wD//wD//wD//wD//wD//wD//wD/p6WlTkxM + TEpKiomJ2dnZ5OTkp6amcnBwXVxcXVxccnBwp6am5OTk2trac3FxRUNDRUNDR0VFU1JSWlhYU1FRR0VF + SUdHdXNz/wD//wD//wD//wD//wD//wD//wD//wD//wD/tbS0XFpaRUNDWFZWYF5eR0VFSEZGVlRUVlRU + SEZGRkREYF5eWFZWRUNDXFtbl5aW/wD/ZGNjXVtbZGJif35+/wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD/cG5uRUNDR0VFb21turm5397e397eurm5cG5uR0VFRUNDb21t/wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/YmBgSEZGjYyM + 6urq/v7+////////////6urqjYyMSEZGYmBg/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD/hYSERkREgYCA7+/v////////////////////////7+/vgYCA + RkREhoSE/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + TkxMXlxc3Nzc////////////////////////////////3NzcXlxcTkxM/wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/hIODRkREoaCg/f39//////////////////// + /////////////f39oaCgRkREhYSE/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD/W1lZV1VV3Nzc////////////////////////////////////////3dzcVlRUW1lZ/wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/xcXFSkhIdnV19vb2//////// + ////////////////////////////////9vb2d3V1SkhIxcTE/wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD/rKurRUNDk5KS/f39//////////////////////////////////////// + /f39k5KSRUNDrKur/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/o6KiRUND + n52d////////////////////////////////////////////////n56eRUNDo6Ki/wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/rq2tRUNDkpCQ/f39//////////////////////// + /////////////////f39kY+PRUNDrq2t/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD/S0lJb21t8/Ly////////////////////////////////////////8/Lyb21tS0lJ/wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ZGJiTUtLxcXF//////// + ////////////////////////////////xcXFTUtLZGJi/wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD/o6KiR0VFbm1t5eTk////////////////////////////////5OTk + bm1tR0VFo6Ki/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + c3JyRkREeXd329vb/f39/////////////////f393NvbeXd3RkREc3Jy/wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/a2lpRkREXVxcnpyc0NDQ4+Pj4+Pj + 0dDQn56eXlxcRkREbGpq/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD/hYSETkxMRUNDTkxMWFdXWFdXTkxMRURETkxMhoWF/wD//wD//wD//wD/ + /wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + jYyMYF5eSUdHSUdHYF5ejIuL/wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD//wD/ + /wD//wD/ + + + + + Qk02EAAAAAAAADYAAAAoAAAAIAAAACAAAAABACAAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAPz8/EERD + Q7lFQ0P+RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VD + Q/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUJC7ERDQ7ZGQ0Ni/wD///8A////AP///wD///8A + //9HPz8gREND30VDQ/tFQ0PjREND30RDQ99EQ0PfREND30RDQ99EQ0PfREND30RDQ99EQ0PfREND30RD + Q99EQ0PfREND30VCQuFFQ0P3RUND/0VDQ/9EQkL8REJC7URDQ+NFQ0PrRUND+0RCQvhFQkK8REREOP8A + ////AP///wD//0c/PyBEQ0PfREND40LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/RUJCXERCQupEQkL9RUJCzkVDQ25CyFP/QshT/0LIU/9DQ0NpRUJCykRC + QvxFQ0PVREREOP8A////AP//Rz8/IERDQ99EQ0PfQshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9FQ0PAREJC/EVDQ61CyFP/QshT/0LIU/9FQkKhQshT/0LI + U/9CyFP/RUJCqERCQvxFQkK8RUVFFv8A//9HPz8gREND30RDQ99CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/Q0NDZkRDQ/lFQkLOQshT/0LIU/9CyFP/RUNDfEVD + Q/5FQ0N8QshT/0LIU/9CyFP/RUJCykRCQvhERERh/wD//0ZGRh1EQ0PcREJC4kLIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9EQ0OyRUND+0VDQ25CyFP/QshT/0LI + U/9FQ0OARUND/0VDQ4BCyFP/QshT/0LIU/9DQ0NpRUND+0RDQ67/AP//SDw8FURCQtBFQkLsQshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0VCQtZEQkLtQshT/0LI + U/9FQ0N8RUNDgEVDQ8BFQ0P/RUNDwEVDQ4BFQ0N8QshT/0LIU/9EQ0PrREJC0/8A////AP//REFBskVD + Q/pEQUFZQshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/REND30RD + Q+NCyFP/RUJCoUVDQ/5FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/5FQkKhQshT/0VCQuFFQkLd/wD///8A + //9FQ0N5RUND/UVDQ55CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9EQkLXRUJC7ELIU/9CyFP/RUNDfEVDQ4BFQ0PARUND/0VDQ8BFQ0OARUNDfELIU/9CyFP/REND60RC + QtP/AP///wD//0RERDRFQ0PoREND40LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0RCQrNFQ0P7Q0FBbULIU/9CyFP/QshT/0VDQ4BFQ0P/RUNDgELIU/9CyFP/QshT/0ND + Q2lFQ0P7RENDrv8A////AP///wD//0RCQqBEQkL9RENDn0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/RUJCZ0VDQ/lEQ0PNQshT/0LIU/9CyFP/RUNDfEVDQ/5FQ0N8QshT/0LI + U/9CyFP/RUJCy0RCQvhEQUFh/wD///8A////AP//RkFBM0RCQt9EQkL0REREcELIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/RENDwURCQvxFQkKsQshT/0LIU/9CyFP/RUJCoULI + U/9CyFP/QshT/0VCQqlEQkL8RUJCvP8A////AP///wD///8A////AP//REFBZURCQvFEQkLtREREcELI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/REND20RCQvxEQ0PNQ0NDaULI + U/9CyFP/QshT/0ZDQ2lFQkLKREJC/EVDQ9VEREQ4/wD///8A////AP///wD///8A////AP//RkFBeERC + QvFEQkL0RENDn0LIU/9CyFP/REJCd0VCQsBEQ0PcREND3EVCQsBEQkJ3QshT/0LIU/9FQkK/RUND/0VD + Q/9FQ0P7REND6kVCQuFFQ0PrRUND+0RCQvhFQkK8REREOP8A////AP///wD///8A////AP///wD///8A + ////AP//REJCZERCQt5EQkL9RUND5EVCQtlFQ0P7REJC+UVDQ+dFQ0PnREJC+URCQvxFQkLZRUND5ERC + Qv1EQ0PeREJCjURDQ65EQ0PTRUJC3URCQtNEQ0OuREFBYf8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD//0VCQsNFQ0P/RUND+0RCQsREQUFdQshT/0LIU/9EQUFdRUJCw0VD + Q/tFQ0P/REJCxP8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP//RUJC1kVDQ/pFQ0ObQshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/RUNDm0VDQ/pFQkLW/wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD//0VDQ6ZEQkL8RENDq0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/RENDq0RCQvxFQkKl/wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A//9DQ0NLREJC8UVDQ9xCyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/RUND3ERCQvFDQ0NL/wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//0RDQ6dEQkL8REJCf0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9EQkJ/REJC/EVDQ6b/AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//9EREQlRUND4EVC + QuVCyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9EQkLmRUND4P8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//0RE + RE5FQ0P3RENDukLIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0VD + Q7pFQ0P3REFBTv8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP//REJCcEVDQ/5FQ0OTQshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/RUNDk0VDQ/5EQkJw/wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A//9FQ0N9RUND/0ZCQoNCyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9GRESDRUND/0VDQ33/AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD//0VDQ25FQ0P+RkJClULIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0VCQpZFQ0P+RUNDbv8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP//RkNDSERCQvVEQkLEQshT/0LIU/9CyFP/QshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/REJCxERCQvVGQ0NI/wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A//9IPz8cREJC00RCQvJEREROQshT/0LI + U/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0RERE5EQkLyREJC0/8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//9DQUF8RUND+0RD + Q8VCyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/RENDxUVDQ/tDQUF8/wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//0JC + QhtEQ0O+REJC/EVCQrdCyFP/QshT/0LIU/9CyFP/QshT/0LIU/9CyFP/QshT/0VCQrdEQkL8RENDvv8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD//0dCQjJFQkLKREJC/ERDQ9xFQUGEQshT/0LIU/9CyFP/QshT/0ZERINFQ0PcREJC/EVD + Q8lCQkIy/wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD//0RERClDQkKlREJC8URCQv1EQkLxREND40RDQ+NEQkLxREND/URC + QvFFQ0OlREREKf8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD///8A////AP///wD///8A////AP///wD///8A//9GQ0NIRUNDm0VCQtlEQkL4REJC+EVC + QtlEQ0OcRUJCSf8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A + ////AP///wD//w== + + + + + AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAPz8/EERDQ7lFQ0P+RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VD + Q/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUND/0VDQ/9FQ0P/RUJC7ERD + Q7ZGQ0NiRUVFFgAAAAAAAAAAAAAAAAAAAABHPz8gREND30VDQ/tFQ0PjREND30RDQ99EQ0PfREND30RD + Q99EQ0PfREND30RDQ99EQ0PfREND30RDQ99EQ0PfREND30VCQuFFQ0P3RUND/0VDQ/9EQkL8REJC7URD + Q+NFQ0PrRUND+0RCQvhFQkK8REREOAAAAAIAAAAAAAAAAEc/PyBEQ0PfREND40g/PzxHPz8gRz8/IEc/ + PyBHPz8gRz8/IEc/PyBHPz8gRz8/IEc/PyBHPz8gRz8/IEc/PyBHPz8gRUJCXERCQupEQkL9RUJCzkVD + Q25DQ0M1REREKUdCQjJDQ0NpRUJCykRCQvxFQ0PVREREOAAAAAAAAAAARz8/IERDQ99EQ0PfRz8/IAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/PxhFQ0PAREJC/EVD + Q61BQUEjAAAAAURERDhFQkKhREREOAAAAAFHPz8gRUJCqERCQvxFQkK8RUVFFgAAAABHPz8gREND30RD + Q99HPz8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ0NDZkRD + Q/lFQkLOSEFBIwAAAAAAAAAARUNDfEVDQ/5FQ0N8AAAAAAAAAABHR0cgRUJCykRCQvhERERhAAAAAEZG + Rh1EQ0PcREJC4kY/PyQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg4 + OAlEQ0OyRUND+0VDQ24AAAABAAAAAAAAAABFQ0OARUND/0VDQ4AAAAAAAAAAAAAAAAFDQ0NpRUND+0RD + Q64/Pz8ISDw8FURCQtBFQkLsRkFBMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + + + \ No newline at end of file diff --git a/VisualPlugins/TraningControlPlugin/Properties/Resources.Designer.cs b/VisualPlugins/TraningControlPlugin/Properties/Resources.Designer.cs index 4ee9b1bac..3feecc646 100644 --- a/VisualPlugins/TraningControlPlugin/Properties/Resources.Designer.cs +++ b/VisualPlugins/TraningControlPlugin/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // Этот код создан программой. -// Исполняемая версия:4.0.30319.1 +// Исполняемая версия:4.0.30319.42000 // // Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае // повторной генерации кода. @@ -19,7 +19,7 @@ namespace VisualPascalABCPlugins.Properties { // с помощью такого средства, как ResGen или Visual Studio. // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen // с параметром /str или перестройте свой проект VS. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -59,5 +59,15 @@ namespace VisualPascalABCPlugins.Properties { resourceCulture = value; } } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Icon, аналогичного (Значок). + /// + internal static System.Drawing.Icon IconAuthorized { + get { + object obj = ResourceManager.GetObject("IconAuthorized", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } } } diff --git a/VisualPlugins/TraningControlPlugin/Properties/Resources.resx b/VisualPlugins/TraningControlPlugin/Properties/Resources.resx index 7080a7d11..50b5378df 100644 --- a/VisualPlugins/TraningControlPlugin/Properties/Resources.resx +++ b/VisualPlugins/TraningControlPlugin/Properties/Resources.resx @@ -112,9 +112,13 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\IconAuthorized.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/VisualPlugins/TraningControlPlugin/SiteAccessInfo.cs b/VisualPlugins/TraningControlPlugin/SiteAccessInfo.cs new file mode 100644 index 000000000..91960d69a --- /dev/null +++ b/VisualPlugins/TraningControlPlugin/SiteAccessInfo.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace DBAccessPluginNamespace +{ + public enum UserTypeEnum {None, Student, Teacher, Admin }; + + // Информация о пользователе для доступа к сайту, а также для работы с сайтом + // Это можно сохранять между запусками программы + public class SiteAccessProvider + { + // Данные о пользователе + public string ShortFIO { get; set; } = ""; + public string FullFIO { get; set; } = ""; + public string Password { get; set; } = ""; + public string Group { get; set; } = ""; + public UserTypeEnum UserType { get; set; } = UserTypeEnum.None; + + // Базовый адрес папки со скриптами (адрес сервера) + public string ServAddr = ""; + + // Клиент для обработки запросов http + private HttpClient client = null; + + /// + /// Запрос на добавление информации об активности в БДИм + /// + /// Имя задания + /// Имя урока + /// Тип записи - например, выполнено или нет задание + /// Дополнительные данные - например, текст программы + /// + async public Task SendPostRequest(string TaskName, string LessonName, string TypeString, string ContentInfo) + { + // Если не выполнен вход, то выход с ошибкой + if (UserType == UserTypeEnum.None) return "Error"; + + // Если не выполнен вход, то выход с ошибкой + if (UserType != UserTypeEnum.Student) return "Cannot write activity, because you're teacher!"; + + // Если клиент ещё не создан был, пересоздаём + if (client == null) client = new HttpClient(); + // Словарик для параметров запроса + var values = new Dictionary + { + //`id`, `pupilId`, `taskName`, `lessonName`, `type`, `content`, `time`, `IP` + { "shortFIO", ShortFIO }, // shortFIO или FIO, и они должны совпадать с такими же в базе + {"FIO", FullFIO }, + { "taskName", TaskName }, + { "lessonName", LessonName }, + { "type", TypeString }, + { "content", ContentInfo }, + { "password", Password } + }; + // Отправка запроса на сервер + var content = new FormUrlEncodedContent(values); + var response = await client.PostAsync(ServAddr + "//add.php", content); + return await response.Content.ReadAsStringAsync(); + } + + public void Clear() + { + ShortFIO = ""; + FullFIO = ""; + Password = ""; + Group = ""; + UserType = UserTypeEnum.None; + } + + /// + /// Получение начальной информации (начальная страница) + /// + /// + async public Task GetContents() + { + // Если клиент ещё не создан был, пересоздаём + if (client == null) client = new HttpClient(); + // Тут не столь важно что отправлять, можно и пустой список параметров + var values = new Dictionary + { + { "password", "123" }, + }; + + var content = new FormUrlEncodedContent(values); + var response = await client.PostAsync(ServAddr + "/index.php", content); + return await response.Content.ReadAsStringAsync(); + } + /// + /// Получить из БД список групп + /// + /// + async public Task GetGroupsNames(string ServerAddr = "") + { + // Этот метод может быть вызван без предварительного входа + if (ServerAddr != "") + ServAddr = ServerAddr; + if (ServAddr == "") return "Error"; + + // Если клиент ещё не создан был, пересоздаём + if (client == null) client = new HttpClient(); + var values = new Dictionary(); + var content = new FormUrlEncodedContent(values); + var response = await client.PostAsync(ServAddr + "/groupslist.php", content); + return await response.Content.ReadAsStringAsync(); + } + + /// + /// Получить из БД список учеников определенной группы + /// + /// + async public Task GetUsersNames(string GroupName, string ServerAddr = "") + { + // Этот метод может быть вызван без предварительного входа + if (ServerAddr != "" || GroupName == "") + ServAddr = ServerAddr; + if (ServAddr == "") return "Error"; + // Если клиент ещё не создан был, пересоздаём + if (client == null) client = new HttpClient(); + Group = GroupName; + var values = new Dictionary + { + //`id`, `pupilId`, `taskName`, `lessonName`, `type`, `content`, `time`, `IP` + { "userGroup", Group } // shortFIO или FIO, и они должны совпадать с такими же в базе + }; + + var content = new FormUrlEncodedContent(values); + var response = await client.PostAsync(ServAddr + "/userslist.php", content); + return await response.Content.ReadAsStringAsync(); + } + + async public Task Login(string shortFIO, string fullFIO, string password, string ServerAddr = "") + { + // Если передана строка адреса - то и хорошо, а если нет, то используем предыдущее значение + Clear(); + if (ServerAddr != "") + ServAddr = ServerAddr; + if (ServAddr == "" && ServerAddr == "") return "Error"; + + if (shortFIO == "" && fullFIO == "") return "Error"; + ShortFIO = shortFIO; + FullFIO = fullFIO; + Password = password; + if (client == null) client = new HttpClient(); + + // Словарик для параметров запроса + var values = new Dictionary + { + //`id`, `pupilId`, `taskName`, `lessonName`, `type`, `content`, `time`, `IP` + { "shortFIO", ShortFIO }, // shortFIO или FIO, и они должны совпадать с такими же в базе + { "FIO", FullFIO }, + { "password", Password} + }; + // Отправка запроса на сервер + var content = new FormUrlEncodedContent(values); + var response = await client.PostAsync(ServAddr + "/login.php", content); + string responseText = await response.Content.ReadAsStringAsync(); + + // Разобрать ответ от сервера - как пары key:value; + // Это сложно, т.к. тут могут быть сообщения об ошибках + + + //return responseText; + var pieces = responseText.Split(';'); + + // Сбрасываем тип пользователя, по нему и будем проверять успешность ответа + // В сообщениях об ошибках его не должно быть + + foreach(var s in pieces) + { + if (s.IndexOf(':') < 1) continue; + var pair = s.Split(':'); + switch(pair[0]) + { + case "FIO" : FullFIO = pair[1]; break; + case "ShortFIO": ShortFIO = pair[1]; break; + case "type" : { + if (pair[1] == "prepod") UserType = UserTypeEnum.Teacher; + else if (pair[1] == "student") UserType = UserTypeEnum.Student; + break; + } + } + } + + if(UserType == UserTypeEnum.None) + { + Clear(); + return responseText; + } + return "Success"; + } + + // Так как мы на сервере пока ничего не запоминаем, то процесс выхода - просто стереть всё + public void Logout() + { + // Данные о пользователе + Clear(); + + if (client != null) + client.Dispose(); + client = null; + } + } +} diff --git a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs index cf213e23d..6508cf2ed 100644 --- a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs +++ b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs @@ -5,43 +5,24 @@ using System.Text; using System.Linq; using PascalABCCompiler.SyntaxTreeConverters; using PascalABCCompiler.SyntaxTree; +using DBAccessPluginNamespace; namespace VisualPascalABCPlugins { - /*public class TeacherContolConverter: ISyntaxTreeConverter - { - public string Name { get => "TeacherContolConverter"; } - public syntax_tree_node Convert(syntax_tree_node root) - { - var program = root as program_module; - if (program == null) // если это не главная программа, то не преобразовывать - return root; - var FileName = program.file_name; - var fi = new System.IO.FileInfo(FileName); - var SourceFileDirectory = fi.DirectoryName; - - var FullLightPTName = System.IO.Path.Combine(SourceFileDirectory, "lightpt.dat"); - if (!System.IO.File.Exists(FullLightPTName)) - return root; - - if (program.used_units == null) - program.used_units = new uses_list(); - program.used_units.Add(new unit_or_namespace("LightPT", null)); - program.used_units.Add(new unit_or_namespace("Tasks", null)); - return root; - } - }*/ - //имя класса *_VisualPascalABCPlugin public class VisualPascalABCPlugin_TeacherControlPlugin : IVisualPascalABCPlugin { - private const string LabelEntered = "Личный кабинет: "; - private const string LabelNotEntered = "Личный кабинет: вход не выполнен"; + private const string LabelEntered = "Авторизация: "; + private const string LabelNotEntered = "Авторизация: вход не выполнен"; public static string StringsPrefix = "VPP_REGISTER_AND_CONTROL_PLUGIN_"; IVisualEnvironmentCompiler VisualEnvironmentCompiler; IWorkbench Workbench; - private TeacherControlForm RegisterForm = new TeacherControlForm(); + //private TeacherControlForm RegisterForm = new TeacherControlForm(); // старая форма авторизации + //private LoginForm RegisterFormNew = new LoginForm(); // новая форма авторизации + // User + SiteAccessProvider User = new SiteAccessProvider(); + private PluginGUIItem Item; public string Name { get => "Teacher Control Plugin"; } public string Version { get => "0.1"; } @@ -49,27 +30,53 @@ namespace VisualPascalABCPlugins public string Login = null; public string Password = null; - public void Execute() - { - var dr = RegisterForm.ShowDialog(); - if (RegisterForm.Registered) - Item.Hint = LabelEntered + RegisterForm.Login; - else Item.Hint = LabelNotEntered; - } + + public LoginForm loginForm; + + bool firstTime = true; + public ToolStripMenuItem menuItem = null; + public ToolStripButton toolStripButton = null; public VisualPascalABCPlugin_TeacherControlPlugin(IWorkbench Workbench) { + loginForm = new LoginForm(this); this.Workbench = Workbench; VisualEnvironmentCompiler = Workbench.VisualEnvironmentCompiler; - RegisterForm.VisualEnvironmentCompiler = VisualEnvironmentCompiler; + //var tbitem = Workbench.MainForm.Controls.Find("", true); + // RegisterForm.VisualEnvironmentCompiler = VisualEnvironmentCompiler; // Пока форма регистрации никак не связана с компилятором // Регистрация обработчика this.Workbench.ServiceContainer.RunService.Starting += RunStartingHandler; //Workbench.ServiceContainer.BuildService.BeforeCompile += BeforeCompileHandler; } + public void Execute() + { + if (firstTime) + { + firstTime = false; + menuItem = (ToolStripMenuItem)Item.menuItem; + toolStripButton = (ToolStripButton)Item.toolStripButton; + } + + User.ServAddr = "https://air.mmcs.sfedu.ru/pascalabc"; + loginForm.SiteProvider = User; + + loginForm.ShowDialog(); // OK никогда не будет + /*if (loginForm.Authorized) + { + toolStripButton.ToolTipText = "Авторизация выполнена"; + toolStripButton.Image = loginForm.PluginImageAuthorized.Image; + } + else + { + toolStripButton.ToolTipText = "Авторизация: вход не выполнен"; + toolStripButton.Image = loginForm.PluginImage.Image; + }*/ + } + public void GetGUI(List MenuItems, List ToolBarItems) { - Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", RegisterForm.PluginImage.Image, RegisterForm.PluginImage.BackColor, Execute); + Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", loginForm.PluginImage.Image, loginForm.PluginImage.BackColor, Execute); MenuItems.Add(Item); ToolBarItems.Add(Item); } @@ -99,10 +106,10 @@ namespace VisualPascalABCPlugins private void RunStartingHandler(string filename) { - if (RegisterForm.Registered) + /*if (RegisterForm.Registered) { System.IO.File.AppendAllText("d:\\runs.txt", filename + " " + DateTime.Now + '\n'); - } + }*/ } } } diff --git a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.csproj b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.csproj index 2166faf93..261967dcb 100644 --- a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.csproj +++ b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -15,7 +15,7 @@ 4.0 - v4.0 + v4.7.1 publish\ true @@ -43,6 +43,7 @@ 4 AllRules.ruleset true + false pdbonly @@ -52,20 +53,29 @@ prompt 4 AllRules.ruleset + false + + + Form + + + LoginForm.cs + True True Resources.resx + Form @@ -76,6 +86,9 @@ + + LoginForm.cs + Designer ResXFileCodeGenerator @@ -137,6 +150,15 @@ true + + + + + + + + +