diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-06-24 09:49:45 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-06-24 09:49:45 +0300 |
| commit | 5095a1dd5f65a7659083cae6dfccb34007720ee9 (patch) | |
| tree | 62b46d5b437c0d9236827ec46357dd1b1b18c946 | |
| parent | 121c706c24da22e48b0e4d4dacc7ade8fef757bb (diff) | |
| parent | c6b1a719bac638a647dc2e4af51ad888c9f5039d (diff) | |
| download | Tango-5095a1dd5f65a7659083cae6dfccb34007720ee9.tar.gz Tango-5095a1dd5f65a7659083cae6dfccb34007720ee9.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/_git/Tango
54 files changed, 1305 insertions, 464 deletions
diff --git a/Software/DB/Tango.db b/Software/DB/Tango.db Binary files differindex 20371c56a..a42b5d174 100644 --- a/Software/DB/Tango.db +++ b/Software/DB/Tango.db diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf Binary files differindex 089e523ec..b847f2e6f 100644 --- a/Software/DB/Tango.mdf +++ b/Software/DB/Tango.mdf diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf Binary files differindex 93a65856b..d9e6c0c96 100644 --- a/Software/DB/Tango_log.ldf +++ b/Software/DB/Tango_log.ldf diff --git a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c index e8779d265..23560bd06 100644 --- a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c +++ b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c @@ -27,6 +27,10 @@ #include <PMR/Diagnostics/StartDiagnosticsResponse.pb-c.h> #include <PMR/Diagnostics/StopDiagnosticsRequest.pb-c.h> #include <PMR/Diagnostics/StopDiagnosticsResponse.pb-c.h> +#include <PMR/Diagnostics/Event.pb-c.h> +#include <PMR/Diagnostics/EventType.pb-c.h> +#include "PMR/debugging/DebugLogCategory.pb-c.h" + char DiagnosticsToken[36] = {0}; bool DiagnosticsActive = false; @@ -131,8 +135,88 @@ void AlarmHandler_SendDiagnostics(void) return ; } +/*typedef enum _EventType { + EVENT_TYPE__ThreadBreak = 0, + EVENT_TYPE__ThreadTensionControlFailure = 1, + EVENT_TYPE__FeederConeInsufficiant = 2, + EVENT_TYPE__WinderGeneralError = 3, + EVENT_TYPE__WinderConeNotExists = 4, + EVENT_TYPE__ThreadFeedingGeneralError = 5, + EVENT_TYPE__DyeingHeadOverTemperature = 6, + EVENT_TYPE__DHThermalCutoff = 7, + EVENT_TYPE__DryerOverTemperature = 8, + EVENT_TYPE__DryerThermalCutoff = 9, + EVENT_TYPE__DyeingHeadHeatersCurrentOutOfRange = 10, + EVENT_TYPE__DryerHeatersCurrentOutOfRange = 11, + EVENT_TYPE__DryerDHeadCoverOpen = 12, + EVENT_TYPE__AirFilterClogged = 13, + EVENT_TYPE__AirFilterNotInstalled = 14, + EVENT_TYPE__WHSFailure = 15, + EVENT_TYPE__WasteContainerIsAlmostFull = 16, + EVENT_TYPE__WasteContainerIsFull = 17, + EVENT_TYPE__DispenserEmpty = 18, + EVENT_TYPE__DispenserLowLevel = 19, + EVENT_TYPE__DispenserRefillFailure = 20, + EVENT_TYPE__MidTankEmpty = 21, + EVENT_TYPE__MidTankLowLevel = 22, + EVENT_TYPE__MidTankNotInPlace = 23, + EVENT_TYPE__SystemBITFail = 24, + EVENT_TYPE__GeneralInternalOverTemperature = 25, + EVENT_TYPE__MachineCoverOpen = 26, + EVENT_TYPE__EmergencyPushButtonPressed = 27, + EVENT_TYPE__SystemGeneralError = 28, + EVENT_TYPE__RequestSent = 29, + EVENT_TYPE__ResponseReceived = 30, + EVENT_TYPE__RequestFailed = 31, + EVENT_TYPE__ApplicationException = 32, + EVENT_TYPE__ApplicationInformation = 33, + EVENT_TYPE__ApplicationStarted = 34, + EVENT_TYPE__ApplicationTerminated = 35, + EVENT_TYPE__RecordingStarted = 36, + EVENT_TYPE__RecordingStopped = 37 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(EVENT_TYPE) +} EventType; + * */ +uint32_t AlarmHandlingConsequentActions(EventType EventId, DebugLogCategory Severity) +{ + switch (Severity) + { + case DEBUG_LOG_CATEGORY__Warning: + + //raise flag fr next job + break; + case DEBUG_LOG_CATEGORY__Error: + AbortJob(NULL,event_type__descriptor.name[EventId]); +//Stop Job + break; + case DEBUG_LOG_CATEGORY__Critical: + EndState(NULL,event_type__descriptor.name[EventId]); + //stop job + //turn machine off + break; + case DEBUG_LOG_CATEGORY__Debug: + case DEBUG_LOG_CATEGORY__Info: + default: + //do nothing + break; + + } +} + uint32_t AlarmHandlingLoop(uint32_t tick) { + //read dispensers limit switches. 25 - send warning. up - stop job and send alarm + + //Cone missing + //Dyeing head over temperature + //mixer over temperature + //dryer over temperature + //heaters failure + //dispenser pressure + //valve OCD + //Motor Status + //machine cover open + return OK; } void SendDiagnostics(void) diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c index 38ae19f36..ad3aaff6f 100644 --- a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c @@ -41,8 +41,8 @@ typedef struct HeatersControlMessage{ }HeatersControlMessageStruc; /******************** GLOBAL PARAMETERS ********************************************/ -HeaterCommand HeaterCmd[MAX_HEATERS_NUM] = {}; -uint32_t ControlIdtoHeaterId [MAX_HEATERS_NUM] = {0xFF}; +HeaterCommand HeaterCmd[MAX_HEATERS_NUM]; +uint32_t ControlIdtoHeaterId [MAX_HEATERS_NUM] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; uint32_t DryerHeaterMaxTempControl = 0xFF; uint32_t DryerInternalPT100Id = ANALOG_DRYER_TEMP2; diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c index f5462e398..fafc43fb5 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -15,6 +15,8 @@ #include "PMR/Printing/JobSegment.pb-c.h" #include "PMR/Printing/JobTicket.pb-c.h" +#include <utils/ustdlib.h> + #include "StateMachines/Printing/PrintingSTM.h" #include "drivers/Motors/Motor.h" @@ -178,7 +180,7 @@ uint32_t ThreadLengthCBFunction(uint32_t IfIndex, uint32_t ReadValue) pooler_counter++; if (pooler_counter%10 == 0) { - SendJobProgress(CurrentProcessedLength/CurrentRequestedLength,CurrentSegmentId,false); + SendJobProgress(CurrentProcessedLength/CurrentRequestedLength,CurrentSegmentId,false, "Progress"); //SendJobProgress(/*KeepNormalizedError*/MotorControlConfig[index].m_calculatedError,CurrentSegmentId,false); } @@ -259,6 +261,8 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) int32_t TranslatedReadValue, avreageSampleValue = 0; uint32_t calculated_speed; double NormalizedError; + char Message[60]; + if (IfIndex>>8 != IfTypeThread) { LOG_ERROR (IfIndex, "Wrong Interface type"); @@ -293,7 +297,8 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) //TranslatedReadValue = 0;//test MotorSamples[index][MotorSamplePointer[index]] = TranslatedReadValue;//(-1 * TranslatedReadValue); MotorSamplePointer[index]++; - if (MotorSamplePointer[index] >= MotorsControl[index].pvinputfilterfactormode) MotorSamplePointer[index] = 0; + if (MotorSamplePointer[index] >= MotorsControl[index].pvinputfilterfactormode) + MotorSamplePointer[index] = 0; for (i=0;i<MotorsControl[index].pvinputfilterfactormode;i++) avreageSampleValue += MotorSamples[index][i]; avreageSampleValue = avreageSampleValue / MotorsControl[index].pvinputfilterfactormode; @@ -301,7 +306,9 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) if ((abs(avreageSampleValue)> DancerStopActivityLimit[index])&&(JobCounter > eOneSecond)) { - EndState(CurrentJob); + usnprintf(Message, 60, "Dancer % limit%d value %d Zero %d",DancerId,DancerStopActivityLimit[index],avreageSampleValue,DancersCfg[DancerId].zeropoint); + + EndState(CurrentJob,Message ); } NormalizedError = avreageSampleValue*NormalizedErrorCoEfficient[index]; MotorControlConfig[index].m_mesuredParam = NormalizedError; @@ -472,7 +479,9 @@ uint32_t ThreadPreSegmentState(void *JobDetails) //set the speed only before the first segment, speed is constant accros job JobTicket* JobTicket = JobDetails; - float process_speed = JobTicket->processparameters->dyeingspeed; + float process_speed; + if (JobTicket->processparameters) + process_speed= JobTicket->processparameters->dyeingspeed; SetOriginMotorSpeed(process_speed); //ControlStart(); @@ -483,14 +492,14 @@ uint32_t ThreadPreSegmentState(void *JobDetails) //only for testing - when control works, these motors will take their speed from the dryer //MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RDRIVING, OriginalMotorSpd_2PPS[FEEDER_MOTOR]); -//#warning rocker disabled - if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].has_directionthreadwize) - MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize); - MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 5); - if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].has_directionthreadwize) - MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_LLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize); - MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 5); -//#warning rocker disabled +#warning rocker disabled +// if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].has_directionthreadwize) +// MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize); +// MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 5); +// if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].has_directionthreadwize) +// MotorSetDirection((TimerMotors_t)HARDWARE_MOTOR_TYPE__MOTO_LLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize); +// MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 5); +#warning rocker disabled // MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_RDRIVING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RDRIVING].directionthreadwize, 0, GPI_LS_RLOADMOTOR_UP, EndState); //TODO @@ -506,6 +515,7 @@ uint32_t ThreadPreSegmentState(void *JobDetails) { ThreadUpdateProcessLength (0,(void *)NULL); PreSegmentReady(Module_Thread,ModuleDone); + JobCounter = 0; InitialProcess = false; } diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c index 0f9a915d0..4d102061b 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c @@ -79,7 +79,7 @@ static ReturnCode ExitState(void *JobDetails); * the array and enum of JobState_t below must be in sync order ***********************************************************************/ //static ReturnCode (* state[])(void *JobDetails) = { IdleState, ValidateState, PrepareState, PrintState, CleanState}; -void AbortJob(void); +void AbortJob(char *Msg); typedef enum @@ -269,7 +269,7 @@ void JobAbortFunc(MessageContainer* requestContainer) AbortJobRequest* request = abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); - EndState(CurrentJob); + EndState(CurrentJob, "Job Aborted by user"); //AbortJob(); AbortJobResponse response = ABORT_JOB_RESPONSE__INIT; @@ -370,24 +370,19 @@ void JobRequestFunc(MessageContainer* requestContainer) //free(requestContainer); } //******************************************************************************************************************** -void SendJobProgress(double percentage, int SegmentId, bool done) +void SendJobProgress(double percentage, int SegmentId, bool done, char *Message) { uint32_t status = NOT_SUPPORTED; MessageContainer responseContainer; uint8_t* container_buffer; - char DoneMsg[13] = "Job Finished"; - char ProgressMsg[13] = "Progress"; - - - JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (done == true) { - jobStatus.message =DoneMsg; + jobStatus.message = Message; jobStatus.has_progress = true; - jobStatus.progress = 100.0; + jobStatus.progress = percentage; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; @@ -396,7 +391,7 @@ void SendJobProgress(double percentage, int SegmentId, bool done) } else { - jobStatus.message =ProgressMsg; + jobStatus.message =Message; jobStatus.has_progress = true; jobStatus.progress = percentage; jobStatus.has_currentsegmentindex = true; @@ -412,7 +407,7 @@ void SendJobProgress(double percentage, int SegmentId, bool done) SendChars((char*)container_buffer, container_size); } -void AbortJob(void) +void AbortJob(char *Msg) { ReturnCode retcode; retcode = JobSuccess; @@ -421,6 +416,7 @@ void AbortJob(void) Message.messageId = Abort; PrtMessage->messageId = PrintSystemFailure; + strcpy(PrtMessage->messageData,Msg); Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c index bead5597d..1164c11f2 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -36,7 +36,7 @@ static uint32_t EntryState(void *JobDetails); static uint32_t PrepareState(void *JobDetails); static uint32_t PreSegmentState(void *JobDetails, int); static uint32_t SegmentState(void *JobDetails, int); - uint32_t EndState(void *JobDetails); + uint32_t EndState(void *JobDetails, char *Message); static uint32_t ExitState(void *JobDetails); /********************************************************************** @@ -263,9 +263,9 @@ static uint32_t SegmentState(void *JobDetails, int SegmentId) } //******************************************************************************************************************** -uint32_t EndState(void *JobDetails) +uint32_t EndState(void *JobDetails, char *Message) { - SendJobProgress(100,0,true); + SendJobProgress(1.00,0,true,Message); if (Configured[Module_Winder]) { @@ -289,13 +289,13 @@ uint32_t EndState(void *JobDetails) ThreadEndState(CurrentJob); } - JobMessageStruc Message; + JobMessageStruc JobMessage; bool retcode = false; - Message.messageId = PrintingResultsOk; - Message.msglen = MAX_MSG_LEN; + JobMessage.messageId = PrintingResultsOk; + JobMessage.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) - retcode = Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); + retcode = Mailbox_post(JobmsgQ , &JobMessage, BIOS_NO_WAIT); return OK; } @@ -353,7 +353,7 @@ void PrintSTMMsgHandler(void * msg) if (SegmentId >= CurrentJob->n_segments) { //if (CurrentJob->) handle distance to spool - EndState(CurrentJob); + EndState(CurrentJob, "Job Ended"); } else { @@ -367,7 +367,7 @@ void PrintSTMMsgHandler(void * msg) case FinishResultsFail: break; case PrintSystemFailure: - EndState(CurrentJob); + EndState(CurrentJob, Message->messageData); break; default: break; diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h index fc6780e94..0a210eeb1 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h @@ -130,8 +130,9 @@ void PrintSTMMsgHandler(void * msg); void JobRequestFunc(MessageContainer* requestContainer); void JobAbortFunc(MessageContainer* requestContainer); +void AbortJob(char *Msg); -void SendJobProgress(double percentage,int SegmentId, bool done); +void SendJobProgress(double percentage,int SegmentId, bool done, char *Message); uint32_t PrintingHWConfiguration(void *Configuration); @@ -139,7 +140,7 @@ uint32_t PrepareReady(int ModuleId, ModuleStateEnum result); uint32_t PreSegmentReady(int ModuleId, ModuleStateEnum result); uint32_t SegmentReady(int ModuleId, ModuleStateEnum result); uint32_t PrintingHWConfiguration(void *Configuration); -uint32_t EndState(void *JobDetails); +uint32_t EndState(void *JobDetails, char *Message); #endif /* STATEMACHINES_PRINTSTM_H_ */ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml index 6c7596015..0858d7e08 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml @@ -17,7 +17,7 @@ <TextBlock Text="EMAIL"></TextBlock> <TextBox Text="{Binding Email}"></TextBox> <TextBlock Text="PASSWORD"></TextBlock> - <PasswordBox MaxLength="30" pass:PasswordHelper.Attach="True" pass:PasswordHelper.Password="{Binding Password,Mode=TwoWay}"></PasswordBox> + <PasswordBox MaxLength="30" pass:PasswordHelper.Attach="True" pass:PasswordHelper.Password="{Binding PasswordGateWay,Mode=TwoWay}"></PasswordBox> </controls:TableGrid> </Grid> </UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs index 2fcf55d27..4e5425138 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs @@ -48,7 +48,9 @@ namespace Tango.MachineStudio.UI.Authentication /// <exception cref="AuthenticationException">Login failed for user " + email</exception> public User Login(string email, string password) { - User user = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email.ToLower() && x.Password == password); + String hash = User.GetPasswordHash(password); + + User user = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email.ToLower() && x.Password == hash); if (user == null) { diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs index 786951b06..f2a4f1143 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs @@ -86,7 +86,15 @@ namespace Tango.MachineStudio.UI.ViewModels cryptographer = new Rfc2898Cryptographer(); Email = _settings.LastLoginEmail; RememberMe = _settings.RememberMe; - Password = cryptographer.Decrypt(_settings.LastLoginPassword); + + try + { + Password = cryptographer.Decrypt(_settings.LastLoginPassword); + } + catch (Exception ex) + { + LogManager.Log(ex); + } } /// <summary> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UpdateService/MachineStudioUpdateService.svc.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UpdateService/MachineStudioUpdateService.svc.cs index 907dcf757..9b03cda30 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UpdateService/MachineStudioUpdateService.svc.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UpdateService/MachineStudioUpdateService.svc.cs @@ -58,7 +58,8 @@ namespace Tango.MachineStudio.UpdateService db.UsersRoles.ToList(); db.RolesPermissions.ToList(); - var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); + String hash = User.GetPasswordHash(request.Password); + var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == hash); if (user != null && user.HasPermission(Permissions.RunMachineStudio)) { @@ -107,7 +108,9 @@ namespace Tango.MachineStudio.UpdateService db.UsersRoles.ToList(); db.RolesPermissions.ToList(); - var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); + String hash = User.GetPasswordHash(request.Password); + + var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == hash); if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersion)) { diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs index 8ca2b948c..a9ac604e6 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobViewVM.cs @@ -10,6 +10,7 @@ using Tango.PPC.Jobs.Messages; using System.Data.Entity; using Tango.Core.Commands; using System.Windows; +using Tango.Touch.Controls; namespace Tango.PPC.Jobs.ViewModels { @@ -71,6 +72,21 @@ namespace Tango.PPC.Jobs.ViewModels set { _customers = value; RaisePropertyChangedAuto(); } } + private String _customersFilter; + /// <summary> + /// Gets or sets the customers filter. + /// </summary> + public String CustomersFilter + { + get { return _customersFilter; } + set { _customersFilter = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Gets or sets the customers automatic complete provider. + /// </summary> + public AutoCompleteProvider<Customer> CustomersAutoCompleteProvider { get; set; } + /// <summary> /// Gets or sets the add solid segment command. /// </summary> @@ -82,8 +98,12 @@ namespace Tango.PPC.Jobs.ViewModels public JobViewVM() { RegisterForMessage<JobSelectedMessage>(HandleJobSelectedMessage); - AddSolidSegmentCommand = new RelayCommand(AddSolidSegment); + + CustomersAutoCompleteProvider = new AutoCompleteProvider<Customer>((customer, filter) => + { + return customer.Name.ToLower().StartsWith(filter.ToLower()); + }); } private void AddSolidSegment() diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml index 932c185af..a7cc548dc 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/Views/JobView.xaml @@ -53,8 +53,8 @@ <TextBlock>Job name:</TextBlock> <touch:TouchTextBox Text="{Binding Job.Name,UpdateSourceTrigger=PropertyChanged}" KeyboardMode="AlphaNumeric" KeyboardAction="Next" KeyboardContainer="{Binding ElementName=Container}" /> - <TextBlock>Customer name:</TextBlock> - <touch:TouchTextBox Text="{Binding Job.Customer.Name}" KeyboardMode="AlphaNumeric" KeyboardAction="Next" KeyboardContainer="{Binding ElementName=Container}" /> + <TextBlock>Customer:</TextBlock> + <touch:TouchAutoComplete Text="{Binding CustomersFilter}" ItemsSource="{Binding Customers}" SelectedItem="{Binding Job.Customer}" DisplayMemberPath="Name" AutoCompleteProvider="{Binding CustomersAutoCompleteProvider}" KeyboardMode="AlphaNumeric" KeyboardAction="Next" KeyboardContainer="{Binding ElementName=Container}" /> <TextBlock>Thread type:</TextBlock> <touch:TouchComboBox ItemsSource="{Binding Rmls}" SelectedItem="{Binding Job.Rml}" DisplayMemberPath="Name" Title="Select Thread Type" /> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs index e78eef13d..a259e303a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs @@ -44,7 +44,8 @@ namespace Tango.PPC.UI.Authentication /// <returns></returns> public User Login(string email, string password) { - CurrentUser = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email && x.Password == password); + String hash = User.GetPasswordHash(password); + CurrentUser = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email && x.Password == hash); CurrentUserChanged?.Invoke(this, CurrentUser); return CurrentUser; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml index c70c07a43..b6f6f4432 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoginView.xaml @@ -19,9 +19,9 @@ <touch:TouchTextBox Text="{Binding Email,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}" Watermark="Email" KeyboardMode="Email" KeyboardAction="Next" KeyboardContainer="{Binding ElementName=keyboardContainer}" /> <touch:TouchTextBox Text="{Binding Password,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True}" IsPassword="True" Margin="0 40 0 0" Watermark="Password" KeyboardMode="AlphaNumeric" KeyboardAction="Go" KeyboardContainer="{Binding ElementName=keyboardContainer}" /> - <CheckBox Margin="0 30 0 0">Keep me logged in.</CheckBox> + <touch:TouchCheckBox Margin="0 30 0 0">Keep me logged in.</touch:TouchCheckBox> - <touch:TouchButton Height="50" Margin="0 30 0 0" CornerRadius="3" IsDefault="True" Command="{Binding LoginCommand}">LOGIN</touch:TouchButton> + <touch:TouchButton Height="60" Margin="0 30 0 0" CornerRadius="3" IsDefault="True" Command="{Binding LoginCommand}">LOGIN</touch:TouchButton> <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0">Forgot password?</TextBlock> </StackPanel> diff --git a/Software/Visual_Studio/Tango.BL/EntitiesExtensions/User.cs b/Software/Visual_Studio/Tango.BL/EntitiesExtensions/User.cs index 321fa5570..0d1e864ee 100644 --- a/Software/Visual_Studio/Tango.BL/EntitiesExtensions/User.cs +++ b/Software/Visual_Studio/Tango.BL/EntitiesExtensions/User.cs @@ -6,11 +6,18 @@ using System.Text; using System.Threading.Tasks; using Tango.BL.Enumerations; using SimpleValidator.Extensions; +using Newtonsoft.Json; +using System.Xml.Serialization; +using Tango.Core.Cryptography; namespace Tango.BL.Entities { public partial class User { + private static IHashGenerator _hashGenerator; + + private bool _passwordGatewayModified = false; + /// <summary> /// Determines whether the user has the specified permission. /// </summary> @@ -44,6 +51,40 @@ namespace Tango.BL.Entities } } + + private String _passwordGateway; + /// <summary> + /// Gets or sets the password gate way. + /// </summary> + [NotMapped] + [JsonIgnore] + [XmlIgnore] + public String PasswordGateWay + { + get + { + return _passwordGateway; + } + set + { + _passwordGateway = value; + Password = GetHashGenerator().Encrypt(_passwordGateway); + RaisePropertyChangedAuto(); + + _passwordGatewayModified = true; + } + } + + protected override void RaisePropertyChanged(string propName) + { + base.RaisePropertyChanged(propName); + + if (propName == nameof(Password)) + { + RaisePropertyChanged(nameof(PasswordGateWay)); + } + } + public override void Validate(ObservablesContext context) { var users = context.Users.ToList(); @@ -58,9 +99,12 @@ namespace Tango.BL.Entities throw new ArgumentException("The specified email address is invalid."); } - if (!Password.IsBetweenLength(4, 30)) + if (_passwordGatewayModified) { - throw new ArgumentException("A user password must be at least 4 characters long and maximum 30."); + if (!PasswordGateWay.IsBetweenLength(4, 30)) + { + throw new ArgumentException("A user password must be at least 4 characters long and maximum 30."); + } } if (Contact != null) @@ -73,5 +117,25 @@ namespace Tango.BL.Entities Address.Validate(context); } } + + /// <summary> + /// Gets the specified password hash. + /// </summary> + /// <param name="password">The password.</param> + /// <returns></returns> + public static String GetPasswordHash(String password) + { + return GetHashGenerator().Encrypt(password); + } + + private static IHashGenerator GetHashGenerator() + { + if (_hashGenerator == null) + { + _hashGenerator = new BasicHashGenerator(); + } + + return _hashGenerator; + } } } diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/BasicHashGenerator.cs b/Software/Visual_Studio/Tango.Core/Cryptography/BasicHashGenerator.cs new file mode 100644 index 000000000..8715d4abe --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Cryptography/BasicHashGenerator.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.Cryptography +{ + /// <summary> + /// Represents a hashing algorithm engine for one-way password encryption. + /// </summary> + /// <seealso cref="Tango.Core.Cryptography.IEncryptor" /> + public class BasicHashGenerator : IHashGenerator + { + /// <summary> + /// Encrypts the specified text using the static salt key. + /// </summary> + /// <param name="text">The text.</param> + /// <returns></returns> + public string Encrypt(string text) + { + return Encrypt(text, "twine-solutions9"); + } + + /// <summary> + /// Encrypts the specified text using the specified salt. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="salt">The key.</param> + /// <returns></returns> + public string Encrypt(string text, string salt) + { + if (salt.Length < 16) + { + salt = salt.PadRight(16); + } + + salt = salt.Substring(0, 16); + + byte[] saltBytes = Encoding.ASCII.GetBytes(salt); + + var pbkdf2 = new Rfc2898DeriveBytes(text, saltBytes, 10000); + byte[] hash = pbkdf2.GetBytes(20); + + byte[] hashBytes = new byte[36]; + Array.Copy(saltBytes, 0, hashBytes, 0, 16); + Array.Copy(hash, 0, hashBytes, 16, 20); + + return Convert.ToBase64String(hashBytes); + } + + /// <summary> + /// Validates the specified text against the specified hash. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="hash"></param> + public bool Validate(string text, string hash) + { + byte[] hashBytes = Convert.FromBase64String(hash); + + byte[] salt = new byte[16]; + Array.Copy(hashBytes, 0, salt, 0, 16); + + var pbkdf2 = new Rfc2898DeriveBytes(text, salt, 10000); + byte[] h = pbkdf2.GetBytes(20); + for (int i = 0; i < 20; i++) + { + if (hashBytes[i + 16] != h[i]) + { + return false; + } + } + + return true; + } + } +} diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/ICryptographer.cs b/Software/Visual_Studio/Tango.Core/Cryptography/ICryptographer.cs index 3148ea4da..3c9497a8b 100644 --- a/Software/Visual_Studio/Tango.Core/Cryptography/ICryptographer.cs +++ b/Software/Visual_Studio/Tango.Core/Cryptography/ICryptographer.cs @@ -7,38 +7,10 @@ using System.Threading.Tasks; namespace Tango.Core.Cryptography { /// <summary> - /// Represents a string encryption and decryption engine. + /// Represents an encryption and decryption engine. /// </summary> - public interface ICryptographer + public interface ICryptographer : IEncryptor, IDecryptor { - /// <summary> - /// Encrypts the specified text. - /// </summary> - /// <param name="text">The text.</param> - /// <returns></returns> - String Encrypt(String text); - /// <summary> - /// Decrypts the specified text. - /// </summary> - /// <param name="text">The text.</param> - /// <returns></returns> - String Decrypt(String text); - - /// <summary> - /// Encrypts the specified text using the specified pass key. - /// </summary> - /// <param name="text">The text.</param> - /// <param name="key">The key.</param> - /// <returns></returns> - String Encrypt(String text, String key); - - /// <summary> - /// Decrypts the specified text using the specified pass key. - /// </summary> - /// <param name="text">The text.</param> - /// <param name="key">The key.</param> - /// <returns></returns> - String Decrypt(String text, String key); } } diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/IDecryptor.cs b/Software/Visual_Studio/Tango.Core/Cryptography/IDecryptor.cs new file mode 100644 index 000000000..b4c7f672b --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Cryptography/IDecryptor.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.Cryptography +{ + /// <summary> + /// Represents a decryption engine. + /// </summary> + public interface IDecryptor + { + /// <summary> + /// Decrypts the specified text using the built-in static key. + /// </summary> + /// <param name="text">The text.</param> + /// <returns></returns> + String Decrypt(String text); + + /// <summary> + /// Decrypts the specified text using the specified pass key. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="key">The key.</param> + /// <returns></returns> + String Decrypt(String text, String key); + } +} diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/IEncryptor.cs b/Software/Visual_Studio/Tango.Core/Cryptography/IEncryptor.cs new file mode 100644 index 000000000..1ac195f20 --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Cryptography/IEncryptor.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.Cryptography +{ + /// <summary> + /// Represents an encryption engine. + /// </summary> + public interface IEncryptor + { + /// <summary> + /// Encrypts the specified text using the built-in static key. + /// </summary> + /// <param name="text">The text.</param> + /// <returns></returns> + String Encrypt(String text); + + /// <summary> + /// Encrypts the specified text using the specified pass key. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="key">The key.</param> + /// <returns></returns> + String Encrypt(String text, String key); + } +} diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/IHashGenerator.cs b/Software/Visual_Studio/Tango.Core/Cryptography/IHashGenerator.cs new file mode 100644 index 000000000..e1c4eb00a --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Cryptography/IHashGenerator.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Core.Cryptography +{ + /// <summary> + /// Represents a hashing generator. + /// </summary> + public interface IHashGenerator : IEncryptor + { + /// <summary> + /// Validates the specified text against the specified hash. + /// </summary> + /// <param name="text">The text.</param> + /// <param name="hash">The hash.</param> + bool Validate(String text, String hash); + } +} diff --git a/Software/Visual_Studio/Tango.Core/Cryptography/Rfc2898Cryptographer.cs b/Software/Visual_Studio/Tango.Core/Cryptography/Rfc2898Cryptographer.cs index c7273d370..5b89ca780 100644 --- a/Software/Visual_Studio/Tango.Core/Cryptography/Rfc2898Cryptographer.cs +++ b/Software/Visual_Studio/Tango.Core/Cryptography/Rfc2898Cryptographer.cs @@ -32,7 +32,7 @@ namespace Tango.Core.Cryptography { if (text.IsNullOrWhiteSpace()) return text; - string EncryptionKey = Properties.Resources.EncryptionPassword; + string EncryptionKey = key; text = text.Replace(" ", "+"); byte[] cipherBytes = Convert.FromBase64String(text); using (Aes encryptor = Aes.Create()) diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs index 12eba6bb3..13e19e2ac 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs @@ -172,6 +172,28 @@ public static class DependencyObjectExtensions } /// <summary> + /// Finds an ancestor that matches the specified criteria. + /// </summary> + /// <param name="dependencyObject">The dependency object.</param> + /// <param name="predicate">The predicate.</param> + /// <returns></returns> + public static DependencyObject FindAncestor(this DependencyObject dependencyObject, Predicate<DependencyObject> predicate) + { + var parent = VisualTreeHelper.GetParent(dependencyObject); + + if (parent == null) return null; + + if (predicate(parent)) + { + return parent; + } + else + { + return FindAncestor(parent, predicate); + } + } + + /// <summary> /// Finds the child of type T. /// </summary> /// <typeparam name="T"></typeparam> diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs index d4507b183..135727735 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs @@ -127,13 +127,20 @@ public static class ObjectExtensions /// <returns></returns> public static Object GetPropertyValueByPath(this object obj, String propertyPath) { - if (propertyPath.Contains('.')) + if (propertyPath != null) { - string[] Split = propertyPath.Split('.'); - string RemainingProperty = propertyPath.Substring(propertyPath.IndexOf('.') + 1); - return GetPropertyValueByPath(obj.GetType().GetProperty(Split[0]).GetValue(obj, null), RemainingProperty); + if (propertyPath.Contains('.')) + { + string[] Split = propertyPath.Split('.'); + string RemainingProperty = propertyPath.Substring(propertyPath.IndexOf('.') + 1); + return GetPropertyValueByPath(obj.GetType().GetProperty(Split[0]).GetValue(obj, null), RemainingProperty); + } + else + return obj.GetType().GetProperty(propertyPath).GetValue(obj, null); } else - return obj.GetType().GetProperty(propertyPath).GetValue(obj, null); + { + return obj.ToString(); + } } } diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj index 1b541c07e..a2f2bcd58 100644 --- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj +++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj @@ -64,7 +64,11 @@ <Compile Include="Commands\RelayCommand.cs" /> <Compile Include="ConcurrentList.cs" /> <Compile Include="CoreSettings.cs" /> + <Compile Include="Cryptography\BasicHashGenerator.cs" /> <Compile Include="Cryptography\ICryptographer.cs" /> + <Compile Include="Cryptography\IDecryptor.cs" /> + <Compile Include="Cryptography\IEncryptor.cs" /> + <Compile Include="Cryptography\IHashGenerator.cs" /> <Compile Include="Cryptography\Rfc2898Cryptographer.cs" /> <Compile Include="DI\ITangoIOC.cs" /> <Compile Include="DI\TangoInjectAttribute.cs" /> diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs new file mode 100644 index 000000000..634f37311 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/AdornerContentPresenter.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Tango.SharedUI.Controls +{ + public class AdornerContentPresenter : Adorner + { + private VisualCollection _Visuals; + private ContentPresenter _ContentPresenter; + + public AdornerContentPresenter(UIElement adornedElement) + : base(adornedElement) + { + _Visuals = new VisualCollection(this); + _ContentPresenter = new ContentPresenter(); + _Visuals.Add(_ContentPresenter); + } + + public AdornerContentPresenter(UIElement adornedElement, Visual content) + : this(adornedElement) + { Content = content; } + + protected override Size MeasureOverride(Size constraint) + { + _ContentPresenter.Measure(constraint); + return _ContentPresenter.DesiredSize; + } + + protected override Size ArrangeOverride(Size finalSize) + { + _ContentPresenter.Arrange(new Rect(0, 0, + finalSize.Width, finalSize.Height)); + return _ContentPresenter.RenderSize; + } + + protected override Visual GetVisualChild(int index) + { return _Visuals[index]; } + + protected override int VisualChildrenCount + { get { return _Visuals.Count; } } + + public object Content + { + get { return _ContentPresenter.Content; } + set { _ContentPresenter.Content = value; } + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index c52e1c175..f877b327f 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -59,6 +59,7 @@ </Compile> <Compile Include="Components\SelectedObject.cs" /> <Compile Include="Components\SelectedObjectCollection.cs" /> + <Compile Include="Controls\AdornerContentPresenter.cs" /> <Compile Include="Controls\HexagonControl.cs" /> <Compile Include="Controls\HiveControl.xaml.cs"> <DependentUpon>HiveControl.xaml</DependentUpon> diff --git a/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs b/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs new file mode 100644 index 000000000..bc6b67bb3 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/AutoCompleteProvider.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Touch.Controls +{ + public interface IAutoCompleteProvider + { + IList Filter(IList list, String filter); + } + + public class AutoCompleteProvider<T> : IAutoCompleteProvider + { + private Func<T, String, bool> _filter; + + public AutoCompleteProvider(Func<T, string, bool> filter) + { + _filter = filter; + } + + public IList Filter(IList list, String filter) + { + return list.Cast<T>().Where(x => _filter(x, filter)).ToList(); + } + } +} diff --git a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs index 37fcac391..d1ece3f34 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs +++ b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchScrollViewer.cs @@ -283,6 +283,49 @@ namespace Tango.Touch.Controls #endregion + #region Attached Properties + + #region Prevent Scroll + + /// <summary> + /// The prevent scroll property + /// </summary> + public static readonly DependencyProperty PreventScrollProperty = + DependencyProperty.RegisterAttached("PreventScroll", + typeof(bool), typeof(LightTouchScrollViewer), + new FrameworkPropertyMetadata(false)); + + /// <summary> + /// Sets the PreventScroll attached property. + /// </summary> + /// <param name="element">The element.</param> + /// <param name="value">if set to <c>true</c> [value].</param> + public static void SetPreventScroll(FrameworkElement element, bool value) + { + element.SetValue(PreventScrollProperty, value); + } + + /// <summary> + /// Gets the PreventScroll attached property. + /// </summary> + /// <param name="element">The element.</param> + /// <returns></returns> + public static bool GetPreventScroll(FrameworkElement element) + { + if (element != null) + { + return (bool)element.GetValue(PreventScrollProperty); + } + else + { + return false; + } + } + + #endregion + + #endregion + #region Touch / Mouse Handlers /// <summary> @@ -297,6 +340,20 @@ namespace Tango.Touch.Controls return; } + var element = e.OriginalSource as FrameworkElement; + + if (element != null) + { + if (element.FindAncestor<LightTouchScrollViewer>() != this) + { + return; + } + + if (GetPreventScroll(element)) return; + var parentPreventScroll = element.FindAncestor((x) => GetPreventScroll(x as FrameworkElement)); + if (parentPreventScroll != null) return; + } + _mouse_down_location = new Point(e.Location.X, e.Location.Y - _grid_content.Margin.Top); IsMouseTouchDown = true; } diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs new file mode 100644 index 000000000..b4bbdfe69 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.Core.Commands; + +namespace Tango.Touch.Controls +{ + public class TouchAutoComplete : TouchInput + { + private TextBox _textBox; + private Popup _popup; + + public String Text + { + get { return (String)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register("Text", typeof(String), typeof(TouchAutoComplete), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); + + public String Watermark + { + get { return (String)GetValue(WatermarkProperty); } + set { SetValue(WatermarkProperty, value); } + } + public static readonly DependencyProperty WatermarkProperty = + DependencyProperty.Register("Watermark", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IList ItemsSource + { + get { return (IList)GetValue(ItemsSourceProperty); } + set { SetValue(ItemsSourceProperty, value); } + } + public static readonly DependencyProperty ItemsSourceProperty = + DependencyProperty.Register("ItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IList EffectiveItemsSource + { + get { return (IList)GetValue(EffectiveItemsSourceProperty); } + private set { SetValue(EffectiveItemsSourceProperty, value); } + } + public static readonly DependencyProperty EffectiveItemsSourceProperty = + DependencyProperty.Register("EffectiveItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public IAutoCompleteProvider AutoCompleteProvider + { + get { return (IAutoCompleteProvider)GetValue(AutoCompleteProviderProperty); } + set { SetValue(AutoCompleteProviderProperty, value); } + } + public static readonly DependencyProperty AutoCompleteProviderProperty = + DependencyProperty.Register("AutoCompleteProvider", typeof(IAutoCompleteProvider), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public object SelectedItem + { + get { return (object)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(object), typeof(TouchAutoComplete), new PropertyMetadata(null, (d, e) => (d as TouchAutoComplete).OnSelectedItemChanged())); + + public String DisplayMemberPath + { + get { return (String)GetValue(DisplayMemberPathProperty); } + set { SetValue(DisplayMemberPathProperty, value); } + } + public static readonly DependencyProperty DisplayMemberPathProperty = + DependencyProperty.Register("DisplayMemberPath", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public DataTemplate ItemTemplate + { + get { return (DataTemplate)GetValue(ItemTemplateProperty); } + set { SetValue(ItemTemplateProperty, value); } + } + public static readonly DependencyProperty ItemTemplateProperty = + DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public DataTemplate SelectedItemTemplate + { + get { return (DataTemplate)GetValue(SelectedItemTemplateProperty); } + set { SetValue(SelectedItemTemplateProperty, value); } + } + public static readonly DependencyProperty SelectedItemTemplateProperty = + DependencyProperty.Register("SelectedItemTemplate", typeof(DataTemplate), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public RelayCommand ItemSelectedCommand + { + get { return (RelayCommand)GetValue(ItemSelectedCommandProperty); } + private set { SetValue(ItemSelectedCommandProperty, value); } + } + public static readonly DependencyProperty ItemSelectedCommandProperty = + DependencyProperty.Register("ItemSelectedCommand", typeof(RelayCommand), typeof(TouchAutoComplete), new PropertyMetadata(null)); + + public double PopupHeight + { + get { return (double)GetValue(PopupHeightProperty); } + set { SetValue(PopupHeightProperty, value); } + } + public static readonly DependencyProperty PopupHeightProperty = + DependencyProperty.Register("PopupHeight", typeof(double), typeof(TouchAutoComplete), new PropertyMetadata(200.0)); + + public TouchAutoComplete() + { + AutoCompleteProvider = new AutoCompleteProvider<Object>((obj, filter) => { return obj.ToString().ToLower().StartsWith(filter.ToLower()); }); + ItemSelectedCommand = new RelayCommand(() => OnSelectedItemChanged()); + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _textBox = GetTemplateChild("PART_TextBox") as TextBox; + _popup = GetTemplateChild("PART_Popup") as Popup; + + _textBox.PreviewKeyUp += _textBox_PreviewKeyUp; + _textBox.GotFocus += _textBox_GotFocus; + _textBox.LostFocus += _textBox_LostFocus; + + OnSelectedItemChanged(); + } + + private void _textBox_LostFocus(object sender, RoutedEventArgs e) + { + _popup.IsOpen = false; + } + + private void _textBox_GotFocus(object sender, RoutedEventArgs e) + { + if (Text != null) + { + _textBox.CaretIndex = _textBox.Text.Length; + } + } + + private void _textBox_PreviewKeyUp(object sender, KeyEventArgs e) + { + if (AutoCompleteProvider != null && ItemsSource != null) + { + EffectiveItemsSource = AutoCompleteProvider.Filter(ItemsSource, Text); + + if (EffectiveItemsSource.Count > 0) + { + _popup.IsOpen = true; + } + else + { + _popup.IsOpen = false; + } + } + } + + private void OnSelectedItemChanged() + { + if (SelectedItem != null && _textBox != null) + { + Text = SelectedItem.GetPropertyValueByPath(DisplayMemberPath).ToString(); + + if (Text != null) + { + _textBox.CaretIndex = _textBox.Text.Length; + } + } + + if (_popup != null) + { + _popup.IsOpen = false; + } + } + + static TouchAutoComplete() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchAutoComplete), new FrameworkPropertyMetadata(typeof(TouchAutoComplete))); + } + } +} diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml new file mode 100644 index 000000000..4974ecdd1 --- /dev/null +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchAutoComplete.xaml @@ -0,0 +1,225 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:keyboard="clr-namespace:Tango.Touch.Keyboard" + xmlns:components="clr-namespace:Tango.Touch.Components" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:localConverters="clr-namespace:Tango.Touch.Converters" + xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI" + xmlns:local="clr-namespace:Tango.Touch.Controls"> + + <ResourceDictionary.MergedDictionaries> + <ResourceDictionary Source="../Resources/Colors.xaml" /> + + <ResourceDictionary> + <converters:StringNullOrEmptyToBooleanConverter x:Key="StringNullOrEmptyToBooleanConverter" /> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" /> + <converters:MathOperatorConverter x:Key="MathOperatorConverter" /> + <converters:DisplayMemberPathConverter x:Key="DisplayMemberPathConverter" /> + </ResourceDictionary> + </ResourceDictionary.MergedDictionaries> + + <Style TargetType="{x:Type local:TouchAutoComplete}"> + <Setter Property="Focusable" Value="False"></Setter> + <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter> + <Setter Property="PopupHeight" Value="150"></Setter> + <Setter Property="keyboard:KeyboardView.Mode" Value="{Binding RelativeSource={RelativeSource Self},Path=KeyboardMode}"></Setter> + <Setter Property="keyboard:KeyboardView.Action" Value="{Binding RelativeSource={RelativeSource Self},Path=KeyboardAction}"></Setter> + <Setter Property="keyboard:KeyboardView.Container" Value="{Binding RelativeSource={RelativeSource Self},Path=KeyboardContainer}"></Setter> + <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"></Setter> + <Setter Property="ItemTemplate"> + <Setter.Value> + <DataTemplate> + <Border> + <Label VerticalAlignment="Center" FontWeight="Normal"> + <Label.Content> + <MultiBinding Converter="{StaticResource DisplayMemberPathConverter}"> + <Binding Path="." /> + <Binding RelativeSource="{RelativeSource AncestorType=local:TouchAutoComplete}" Path="DisplayMemberPath" /> + </MultiBinding> + </Label.Content> + </Label> + </Border> + </DataTemplate> + </Setter.Value> + </Setter> + <Setter Property="SelectedItemTemplate"> + <Setter.Value> + <DataTemplate> + <Label VerticalAlignment="Center"> + <Label.Content> + <MultiBinding Converter="{StaticResource DisplayMemberPathConverter}"> + <Binding Path="." /> + <Binding RelativeSource="{RelativeSource AncestorType=local:TouchAutoComplete}" Path="DisplayMemberPath" /> + </MultiBinding> + </Label.Content> + </Label> + </DataTemplate> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:TouchAutoComplete}"> + <Border x:Name="PART_Border" Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" keyboard:KeyboardView.Container="{TemplateBinding KeyboardContainer}"> + <Grid> + <DockPanel> + <Border DockPanel.Dock="Bottom" Visibility="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=(Validation.HasError),Converter={StaticResource BooleanToVisibilityConverter}}"> + <TextBlock FontSize="12" Foreground="{StaticResource TangoValidationErrorBrush}" Margin="0 5 0 0" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=(Validation.Errors).CurrentItem.ErrorContent}"></TextBlock> + </Border> + <DockPanel> + <Grid DockPanel.Dock="Bottom" Height="2"> + <Rectangle Height="1" Fill="{StaticResource TangoTextWatermarkBrush}" /> + <Rectangle Height="2" RenderTransformOrigin="0.5,0.5" > + <Rectangle.Style> + <Style TargetType="Rectangle"> + <Setter Property="Fill" Value="{StaticResource TangoPrimaryAccentBrush}"></Setter> + <Setter Property="RenderTransform"> + <Setter.Value> + <ScaleTransform ScaleY="1" ScaleX="0" /> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding ElementName=PART_TextBox,Path=IsFocused}" Value="True"> + <DataTrigger.EnterActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1" Duration="00:00:0.4" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="0" Duration="00:00:0.4" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.ExitActions> + </DataTrigger> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=(Validation.HasError)}" Value="True"> + <Setter Property="Fill" Value="{StaticResource TangoValidationErrorBrush}"></Setter> + <Setter Property="RenderTransform"> + <Setter.Value> + <ScaleTransform ScaleY="1" ScaleX="1" /> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Rectangle.Style> + </Rectangle> + </Grid> + + <Grid> + <components:Ripple RippleBrush="{StaticResource TangoRippleDarkBrush}" RippleFactor="15"> + <Grid> + <TextBox Foreground="{TemplateBinding Foreground}" Padding="0 0 0 4" CaretBrush="{StaticResource TangoPrimaryAccentBrush}" FocusVisualStyle="{x:Null}" x:Name="PART_TextBox" Text="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=Text,UpdateSourceTrigger=PropertyChanged}" BorderThickness="0" Background="Transparent"> + <TextBox.Style> + <Style TargetType="TextBox"> + <Setter Property="Opacity" Value="0"></Setter> + <Style.Triggers> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Opacity" Value="1"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </TextBox.Style> + </TextBox> + <ContentControl Focusable="False" IsHitTestVisible="False" Foreground="{TemplateBinding Foreground}" Padding="0 0 0 4" Content="{TemplateBinding SelectedItem}" ContentTemplate="{TemplateBinding SelectedItemTemplate}"> + <ContentControl.Style> + <Style TargetType="ContentControl"> + <Setter Property="Opacity" Value="1"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding ElementName=PART_TextBox,Path=IsFocused}" Value="True"> + <Setter Property="Opacity" Value="0"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ContentControl.Style> + </ContentControl> + <TextBlock IsHitTestVisible="False" Text="{TemplateBinding Watermark}" Foreground="{StaticResource TangoTextWatermarkBrush}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=Text,Converter={StaticResource StringNullOrEmptyToBooleanConverter},UpdateSourceTrigger=PropertyChanged}" Value="True"></Condition> + <Condition Binding="{Binding ElementName=PART_TextBox,Path=IsFocused}" Value="False"></Condition> + <Condition Binding="{Binding ElementName=PART_TextBox,Path=Visibility}" Value="Visible"></Condition> + </MultiDataTrigger.Conditions> + <Setter Property="Visibility" Value="Visible"></Setter> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </Grid> + </components:Ripple> + + <Canvas VerticalAlignment="Top" IsHitTestVisible="False" Margin="0 -4 0 0"> + <Canvas.Style> + <Style TargetType="Canvas"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=Text,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource StringNullOrEmptyToBooleanConverter}}" Value="False"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ElementName=PART_TextBox,Path=IsFocused}" Value="True"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Canvas.Style> + <TextBlock FontWeight="Bold" FontSize="11" Foreground="{StaticResource TangoPrimaryAccentBrush}" Canvas.Top="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight,Converter={StaticResource MathOperatorConverter},ConverterParameter='*-1'}" Text="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=Watermark}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Opacity" Value="0"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=Visibility}" Value="Visible"> + <DataTrigger.EnterActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:0.2" To="1" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:0.2" To="0" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.ExitActions> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </Canvas> + </Grid> + </DockPanel> + </DockPanel> + + <Popup x:Name="PART_Popup" StaysOpen="False" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding PopupHeight}" PopupAnimation="Slide" AllowsTransparency="True" PlacementTarget="{Binding ElementName=PART_Border}" Placement="Bottom"> + <Border Padding="10"> + <Border CornerRadius="3" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <Border.Effect> + <DropShadowEffect ShadowDepth="0" Color="{StaticResource TangoDropShadowColor}" /> + </Border.Effect> + + <local:TouchListBox ItemSelectedCommand="{TemplateBinding ItemSelectedCommand}" ItemsSource="{TemplateBinding EffectiveItemsSource}" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=local:TouchAutoComplete},Path=SelectedItem,Mode=TwoWay}" ItemTemplate="{TemplateBinding ItemTemplate}" SelectionMode="None"> + + </local:TouchListBox> + </Border> + </Border> + </Popup> + </Grid> + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + +</ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs index faed67918..41ff43ef3 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.cs @@ -15,6 +15,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.Core.Commands; using Tango.Core.EventArguments; namespace Tango.Touch.Controls @@ -104,13 +105,31 @@ namespace Tango.Touch.Controls public static readonly DependencyProperty ItemSelectedCommandProperty = DependencyProperty.Register("ItemSelectedCommand", typeof(ICommand), typeof(TouchListBox), new PropertyMetadata(null)); - + public RelayCommand<TouchListBoxItem> ListBoxItemLoadedCommand + { + get { return (RelayCommand<TouchListBoxItem>)GetValue(ListBoxItemLoadedCommandProperty); } + set { SetValue(ListBoxItemLoadedCommandProperty, value); } + } + public static readonly DependencyProperty ListBoxItemLoadedCommandProperty = + DependencyProperty.Register("ListBoxItemLoadedCommand", typeof(RelayCommand<TouchListBoxItem>), typeof(TouchListBox), new PropertyMetadata(null)); public TouchListBox() { _awaitingSelectionItems = new List<TouchListBoxItem>(); Loaded += TouchListBox_Loaded; + + ListBoxItemLoadedCommand = new RelayCommand<TouchListBoxItem>(RegisterListBoxItemEvents); + } + + private void RegisterListBoxItemEvents(TouchListBoxItem item) + { + if (item.Tag == null) + { + item.Tag = 1; + item.RegisterForPreviewMouseOrTouchDown(OnItemMouseDown); + item.RegisterForPreviewMouseOrTouchUp(OnItemMouseUp); + } } private void TouchListBox_Loaded(object sender, RoutedEventArgs e) @@ -149,13 +168,19 @@ namespace Tango.Touch.Controls private void UpdateSelectedItems() { + var selectedItem = GetItems().FirstOrDefault(x => x.IsSelected); + if (selectedItem != null) + { + SelectedItem = selectedItem.DataContext; + } + if (SelectedItems != null) { SelectedItems.Clear(); foreach (var item in GetItems().Where(x => x.IsSelected)) { - SelectedItems.Add(item); + SelectedItems.Add(item.DataContext); } } } diff --git a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml index 6393c5699..8fddd5f28 100644 --- a/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml +++ b/Software/Visual_Studio/Tango.Touch/Controls/TouchListBox.xaml @@ -1,6 +1,7 @@ <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:components="clr-namespace:Tango.Touch.Components" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:localConverters="clr-namespace:Tango.Touch.Converters" xmlns:local="clr-namespace:Tango.Touch.Controls"> @@ -43,6 +44,11 @@ <ItemsControl.ItemTemplate> <DataTemplate> <local:TouchListBoxItem> + <i:Interaction.Triggers> + <i:EventTrigger EventName="Loaded"> + <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=local:TouchListBox},Path=ListBoxItemLoadedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=local:TouchListBoxItem}}" /> + </i:EventTrigger> + </i:Interaction.Triggers> <components:Ripple RippleBrush="{StaticResource TangoRippleDarkBrush}" RippleFactor="30"> <components:Ripple.Style> <Style TargetType="components:Ripple"> diff --git a/Software/Visual_Studio/Tango.Touch/Tango.Touch.csproj b/Software/Visual_Studio/Tango.Touch/Tango.Touch.csproj index f37432f4a..ebbcf650c 100644 --- a/Software/Visual_Studio/Tango.Touch/Tango.Touch.csproj +++ b/Software/Visual_Studio/Tango.Touch/Tango.Touch.csproj @@ -59,7 +59,9 @@ <Compile Include="..\Versioning\Core.cs"> <Link>Core.cs</Link> </Compile> + <Compile Include="Controls\AutoCompleteProvider.cs" /> <Compile Include="Controls\MessageBoxVM.cs" /> + <Compile Include="Controls\TouchAutoComplete.cs" /> <Compile Include="Controls\TouchCheckBox.cs" /> <Compile Include="Controls\TouchComboBox.cs" /> <Compile Include="Controls\TouchExpander.cs" /> @@ -84,6 +86,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Controls\TouchAutoComplete.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Controls\TouchCheckBox.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Software/Visual_Studio/Tango.Touch/Themes/Generic.xaml b/Software/Visual_Studio/Tango.Touch/Themes/Generic.xaml index 2a816f39e..58b13bb8e 100644 --- a/Software/Visual_Studio/Tango.Touch/Themes/Generic.xaml +++ b/Software/Visual_Studio/Tango.Touch/Themes/Generic.xaml @@ -29,6 +29,7 @@ <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Controls/TouchComboBox.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Controls/TouchExpander.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Controls/TouchToggleSlider.xaml" /> + <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Controls/TouchAutoComplete.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Styles/TouchToggleButton.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.Touch;component/Styles/TouchButton.xaml" /> diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index 7ace11c42..4f3accc79 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -201,6 +201,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.PPC.Jobs", "PPC\Modul EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.PPC.Synchronization", "PPC\Modules\Tango.PPC.Synchronization\Tango.PPC.Synchronization.csproj", "{729455D4-C384-4497-AF5D-0A598F86DAC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.HashGenerator", "Utilities\Tango.HashGenerator\Tango.HashGenerator.csproj", "{0440A135-0DF0-4232-AB3C-98B9283123B3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution AppVeyor|Any CPU = AppVeyor|Any CPU @@ -3439,6 +3441,46 @@ Global {729455D4-C384-4497-AF5D-0A598F86DAC6}.Release|x64.Build.0 = Release|Any CPU {729455D4-C384-4497-AF5D-0A598F86DAC6}.Release|x86.ActiveCfg = Release|Any CPU {729455D4-C384-4497-AF5D-0A598F86DAC6}.Release|x86.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|Any CPU.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|ARM.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|ARM.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|ARM64.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|x64.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|x64.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|x86.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.AppVeyor|x86.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|ARM.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|ARM.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|ARM64.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|x64.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|x64.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|x86.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Debug|x86.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|ARM.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|x64.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.DefaultBuild|x86.Build.0 = Debug|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|Any CPU.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|ARM.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|ARM.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|ARM64.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|ARM64.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|x64.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|x64.Build.0 = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|x86.ActiveCfg = Release|Any CPU + {0440A135-0DF0-4232-AB3C-98B9283123B3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3500,6 +3542,7 @@ Global {0048447D-1D94-4E60-9DAD-7349C777CB4E} = {C81ED1A3-D18C-4D80-A8F5-061994A14A60} {096F16C8-6D06-4B5F-9496-B9D2DF2D94A3} = {0048447D-1D94-4E60-9DAD-7349C777CB4E} {729455D4-C384-4497-AF5D-0A598F86DAC6} = {0048447D-1D94-4E60-9DAD-7349C777CB4E} + {0440A135-0DF0-4232-AB3C-98B9283123B3} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} diff --git a/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/Program.cs b/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/Program.cs index cc0bbf159..e04f1a304 100644 --- a/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/Program.cs +++ b/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/Program.cs @@ -16,6 +16,14 @@ namespace Tango.DBObservablesGenerator.CLI { Console.Title = "Tango Observables Generator"; +#if DEBUG + args = new string[] + { + Path.GetFullPath( "..\\..\\Tango.BL"), + "-csharp" + }; +#endif + if (args == null || args.Length < 2) { ExitError("Invalid arguments!"); diff --git a/Software/Visual_Studio/Utilities/Tango.HashGenerator/App.config b/Software/Visual_Studio/Utilities/Tango.HashGenerator/App.config new file mode 100644 index 000000000..8324aa6ff --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.HashGenerator/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /> + </startup> +</configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/Utilities/Tango.HashGenerator/Program.cs b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Program.cs new file mode 100644 index 000000000..7eb6e88b9 --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Program.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Cryptography; + +namespace Tango.HashGenerator +{ + class Program + { + static void Main(string[] args) + { + while (true) + { + Console.Write("Enter password to hash: "); + String password = Console.ReadLine(); + + if (password.ToLower() == "exit") return; + + IHashGenerator hash = new BasicHashGenerator(); + + Console.WriteLine(); + Console.WriteLine("Hash generated: " + hash.Encrypt(password)); + } + } + } +} diff --git a/Software/Visual_Studio/Utilities/Tango.HashGenerator/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f3cdb1807 --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tango.HashGenerator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tango.HashGenerator")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0440a135-0df0-4232-ab3c-98b9283123b3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/Utilities/Tango.HashGenerator/Tango.HashGenerator.csproj b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Tango.HashGenerator.csproj new file mode 100644 index 000000000..cee8566a7 --- /dev/null +++ b/Software/Visual_Studio/Utilities/Tango.HashGenerator/Tango.HashGenerator.csproj @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{0440A135-0DF0-4232-AB3C-98B9283123B3}</ProjectGuid> + <OutputType>Exe</OutputType> + <RootNamespace>Tango.HashGenerator</RootNamespace> + <AssemblyName>Tango.HashGenerator</AssemblyName> + <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Utilities/Tango.SQLiteGenerator.CLI/Program.cs b/Software/Visual_Studio/Utilities/Tango.SQLiteGenerator.CLI/Program.cs index 92ab04ddf..1f28e4e89 100644 --- a/Software/Visual_Studio/Utilities/Tango.SQLiteGenerator.CLI/Program.cs +++ b/Software/Visual_Studio/Utilities/Tango.SQLiteGenerator.CLI/Program.cs @@ -22,6 +22,16 @@ namespace Tango.SQLiteGenerator.CLI { static void Main(string[] args) { + Console.Title = "Tango SQLite Generator"; + +#if DEBUG + args = new string[] + { + Path.GetFullPath( "..\\..\\..\\DB\\Tango.db"), + "CopyAll" + }; +#endif + String sqlitePath = args[0]; Config conf = args.Length > 1 ? (Config)Enum.Parse(typeof(Config), args[1]) : Config.Default; diff --git a/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml index af6e78092..8b6251200 100644 --- a/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml +++ b/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml @@ -17,7 +17,7 @@ <touch:TouchPanel> <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext}"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Width="300" Margin="0 0 0 0"> - <touch:TouchTextBox FontSize="20" Watermark="Email" Text="{Binding Email,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" /> + <!--<touch:TouchTextBox FontSize="20" Watermark="Email" Text="{Binding Email,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" />--> <touch:TouchTextBox IsPassword="True" Margin="0 30 0 0" FontSize="20" Watermark="Password" keyboard:KeyboardView.Action="Go" Text="{Binding Password}" /> <touch:TouchButton Height="50" Margin="0 60 0 0" IsDefault="True" Command="{Binding LoginCommand}">LOGIN</touch:TouchButton> @@ -45,6 +45,8 @@ </touch:TouchExpander> <touch:TouchToggleSlider Height="40" Width="90" Style="{StaticResource TouchToggleButtonCheck}"/> + + <touch:TouchAutoComplete Margin="0 20 0 0" FontSize="20" Watermark="enter something..." ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Persons}" DisplayMemberPath="LastName" /> </StackPanel> </Grid> </touch:TouchPanel> diff --git a/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml.cs index d6f01033e..e952fe594 100644 --- a/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml.cs +++ b/Software/Visual_Studio/Utilities/Tango.UITests/MainWindow.xaml.cs @@ -117,7 +117,7 @@ namespace Tango.UITests Persons.Add(new Person() { Age = i, - FirstName = "Roy " + i.ToString(), + FirstName = i.ToString() + " Roy", LastName = "Ben Shabat " + i.ToString(), Index = i, }); diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs index 5f7c82c65..da3796faf 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs @@ -39,6 +39,7 @@ this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.label2 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); + this.chkSQLite = new System.Windows.Forms.CheckBox(); this.panel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); @@ -46,6 +47,7 @@ // panel1 // this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Controls.Add(this.chkSQLite); this.panel1.Controls.Add(this.btnCancel); this.panel1.Controls.Add(this.btnOK); this.panel1.Controls.Add(this.chkBuildSolution); @@ -59,7 +61,7 @@ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Location = new System.Drawing.Point(0, 0); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(596, 285); + this.panel1.Size = new System.Drawing.Size(596, 327); this.panel1.TabIndex = 2; // // btnCancel @@ -71,7 +73,7 @@ this.btnCancel.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(15)))), ((int)(((byte)(15))))); this.btnCancel.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60))))); this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnCancel.Location = new System.Drawing.Point(349, 230); + this.btnCancel.Location = new System.Drawing.Point(349, 272); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(114, 42); this.btnCancel.TabIndex = 11; @@ -87,7 +89,7 @@ this.btnOK.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(15)))), ((int)(((byte)(15))))); this.btnOK.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60))))); this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnOK.Location = new System.Drawing.Point(469, 230); + this.btnOK.Location = new System.Drawing.Point(469, 272); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(114, 42); this.btnOK.TabIndex = 10; @@ -99,11 +101,11 @@ this.chkBuildSolution.AutoSize = true; this.chkBuildSolution.Cursor = System.Windows.Forms.Cursors.Arrow; this.chkBuildSolution.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.chkBuildSolution.Location = new System.Drawing.Point(27, 196); + this.chkBuildSolution.Location = new System.Drawing.Point(27, 222); this.chkBuildSolution.Name = "chkBuildSolution"; - this.chkBuildSolution.Size = new System.Drawing.Size(108, 20); + this.chkBuildSolution.Size = new System.Drawing.Size(111, 20); this.chkBuildSolution.TabIndex = 9; - this.chkBuildSolution.Text = "Build Solution"; + this.chkBuildSolution.Text = "Build Solution."; this.chkBuildSolution.UseVisualStyleBackColor = true; // // chkUpdateAndBuildPMR @@ -190,12 +192,24 @@ this.label1.Text = "Tango Build Engine"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // + // chkSQLite + // + this.chkSQLite.AutoSize = true; + this.chkSQLite.Cursor = System.Windows.Forms.Cursors.Arrow; + this.chkSQLite.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.chkSQLite.Location = new System.Drawing.Point(27, 196); + this.chkSQLite.Name = "chkSQLite"; + this.chkSQLite.Size = new System.Drawing.Size(252, 20); + this.chkSQLite.TabIndex = 12; + this.chkSQLite.Text = "Generate SQLite DB from SQL Server."; + this.chkSQLite.UseVisualStyleBackColor = true; + // // BuildForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.ClientSize = new System.Drawing.Size(596, 285); + this.ClientSize = new System.Drawing.Size(596, 327); this.ControlBox = false; this.Controls.Add(this.panel1); this.ForeColor = System.Drawing.Color.Gainsboro; @@ -228,5 +242,6 @@ private System.Windows.Forms.CheckBox chkBuildSolution; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.CheckBox chkSQLite; } }
\ No newline at end of file diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.cs index ff75ec321..86ad94a13 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.cs @@ -16,6 +16,7 @@ namespace Tango.BuildExtensions public bool GenerateAndBuildObservables { get; set; } public bool GenerateAutoPmrMessages { get; set; } public bool UpdateAndBuildPmrMessages { get; set; } + public bool GenerateSQLite { get; set; } public bool BuildSolution { get; set; } public BuildForm() @@ -40,6 +41,7 @@ namespace Tango.BuildExtensions GenerateAndBuildObservables = chkGenerateObservables.Checked; GenerateAutoPmrMessages = chkGeneratePMR.Checked; UpdateAndBuildPmrMessages = chkUpdateAndBuildPMR.Checked; + GenerateSQLite = chkSQLite.Checked; BuildSolution = chkBuildSolution.Checked; Close(); diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs deleted file mode 100644 index 7b9493b08..000000000 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs +++ /dev/null @@ -1,138 +0,0 @@ -namespace Tango.BuildExtensions -{ - partial class SelectForm - { - /// <summary> - /// Required designer variable. - /// </summary> - private System.ComponentModel.IContainer components = null; - - /// <summary> - /// Clean up any resources being used. - /// </summary> - /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// <summary> - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// </summary> - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.panel1 = new System.Windows.Forms.Panel(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.lbSTatus = new System.Windows.Forms.Label(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // label1 - // - this.label1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); - this.label1.Dock = System.Windows.Forms.DockStyle.Top; - this.label1.Location = new System.Drawing.Point(0, 0); - this.label1.Margin = new System.Windows.Forms.Padding(0); - this.label1.Name = "label1"; - this.label1.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0); - this.label1.Size = new System.Drawing.Size(483, 29); - this.label1.TabIndex = 0; - this.label1.Text = "Tango Build Extensions"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.label1.UseWaitCursor = true; - // - // panel1 - // - this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panel1.Controls.Add(this.pictureBox1); - this.panel1.Controls.Add(this.lbSTatus); - this.panel1.Controls.Add(this.progressBar1); - this.panel1.Controls.Add(this.label1); - this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel1.Location = new System.Drawing.Point(0, 0); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(485, 156); - this.panel1.TabIndex = 1; - this.panel1.UseWaitCursor = true; - // - // pictureBox1 - // - this.pictureBox1.Image = global::Tango.BuildExtensions.Properties.Resources.machine_trans_small; - this.pictureBox1.Location = new System.Drawing.Point(12, 40); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(63, 68); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pictureBox1.TabIndex = 3; - this.pictureBox1.TabStop = false; - this.pictureBox1.UseWaitCursor = true; - // - // lbSTatus - // - this.lbSTatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lbSTatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lbSTatus.Location = new System.Drawing.Point(41, 56); - this.lbSTatus.Name = "lbSTatus"; - this.lbSTatus.Size = new System.Drawing.Size(404, 44); - this.lbSTatus.TabIndex = 2; - this.lbSTatus.Text = "Initializing..."; - this.lbSTatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.lbSTatus.UseWaitCursor = true; - // - // progressBar1 - // - this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.progressBar1.Location = new System.Drawing.Point(11, 120); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(461, 23); - this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.progressBar1.TabIndex = 1; - this.progressBar1.UseWaitCursor = true; - this.progressBar1.Value = 50; - // - // SelectForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.ClientSize = new System.Drawing.Size(485, 156); - this.ControlBox = false; - this.Controls.Add(this.panel1); - this.ForeColor = System.Drawing.Color.Gainsboro; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "SelectForm"; - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Tango Initializer"; - this.TopMost = true; - this.UseWaitCursor = true; - this.panel1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.ProgressBar progressBar1; - private System.Windows.Forms.Label lbSTatus; - private System.Windows.Forms.PictureBox pictureBox1; - } -}
\ No newline at end of file diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.cs deleted file mode 100644 index 349721155..000000000 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.cs +++ /dev/null @@ -1,33 +0,0 @@ -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; - -namespace Tango.BuildExtensions -{ - public partial class SelectForm : Form - { - public SelectForm() - { - InitializeComponent(); - } - - public void SetStatus(String text) - { - lbSTatus.Text = text; - } - - protected override bool ShowWithoutActivation - { - get - { - return true; - } - } - } -} diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.resx b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.resx deleted file mode 100644 index 1af7de150..000000000 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.resx +++ /dev/null @@ -1,120 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> -</root>
\ No newline at end of file diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj index 7148e4761..ffe4eb0d7 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj @@ -72,12 +72,6 @@ <Compile Include="BuildForm.Designer.cs"> <DependentUpon>BuildForm.cs</DependentUpon> </Compile> - <Compile Include="ProgressForm.cs"> - <SubType>Form</SubType> - </Compile> - <Compile Include="ProgressForm.Designer.cs"> - <DependentUpon>ProgressForm.cs</DependentUpon> - </Compile> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\Resources.Designer.cs"> <AutoGen>True</AutoGen> @@ -240,9 +234,6 @@ <EmbeddedResource Include="BuildForm.resx"> <DependentUpon>BuildForm.cs</DependentUpon> </EmbeddedResource> - <EmbeddedResource Include="ProgressForm.resx"> - <DependentUpon>ProgressForm.cs</DependentUpon> - </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.resx"> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs index 9de557117..624124ef2 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs @@ -41,6 +41,7 @@ namespace Tango.BuildExtensions private const String pmrGeneratorProjectName = "Tango.PMRGenerator.CLI"; private const String pmrProjectName = "Tango.PMR"; private const String protoCliProjectName = "Tango.Protobuf.CLI"; + private const String sqliteProjectName = "Tango.SQLiteGenerator.CLI"; #region Redundant @@ -143,7 +144,7 @@ namespace Tango.BuildExtensions _application = TestStack.White.Application.Attach(_vsProcess); _window = _application.GetWindow(vsWindowTitle); - OpenProgressForm(); + OpenVSProgress("Tango Build Engine", "Initializing...", true); try { @@ -163,18 +164,22 @@ namespace Tango.BuildExtensions { UpdateAndBuildPmrMessages(); } + if (buildForm.GenerateSQLite) + { + GenerateSQLite(); + } if (buildForm.BuildSolution) { BuildSolution(); } - SetProgressText("Done!"); + SetVSProgress("Done!"); Wait(1000); - CloseProgressForm(); + CloseVSProgress(); } catch (Exception ex) { - CloseProgressForm(); + CloseVSProgress(); ShowMessage(ex.Message); } }); @@ -191,7 +196,7 @@ namespace Tango.BuildExtensions var projectItems = project.ProjectItems.OfType<ProjectItem>().ToList(); - SetProgressText("Locating " + edmxModelName + " scheme..."); + SetVSProgress("Locating " + edmxModelName + " scheme..."); var items = GetProjectItems(project); @@ -202,20 +207,20 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate " + edmxModelName + "!"); } - SetProgressText("Expanding diagram..."); + SetVSProgress("Expanding diagram..."); edmx.ExpandView(); - SetProgressText("Opening edmx diagram window..."); + SetVSProgress("Opening EDMX diagram window..."); Window win = edmx.Open(EnvDTE.Constants.vsViewKindPrimary); win.Visible = true; - SetProgressText("Waiting for edmx diagram window..."); + SetVSProgress("Waiting for EDMX diagram window..."); _window.WaitTill(() => _window.Get(SearchCriteria.ByText(edmxModelName + " [Diagram1]")) != null); - SetProgressText("Cleaning up edmx scheme..."); + SetVSProgress("Cleaning up EDMX scheme..."); DTE.MainWindow.Activate(); DTE.ExecuteCommand("Edit.SelectAll"); @@ -225,7 +230,7 @@ namespace Tango.BuildExtensions _window.WaitWhileBusy(); - SetProgressText("Reinitializing edmx scheme..."); + SetVSProgress("Reinitializing EDMX scheme..."); var window = WindowInfo.GetWindow(edmxModelName + " [Diagram1]*"); window.SetActive(); @@ -256,13 +261,13 @@ namespace Tango.BuildExtensions updateWindow.PressKey(KeyboardInput.SpecialKeys.RETURN); - SetProgressText("Generating edmx scheme..."); + SetVSProgress("Generating EDMX scheme..."); WaitForWindowClose("Update Wizard"); _window.WaitWhileBusy(); - SetProgressText("Saving changes..."); + SetVSProgress("Saving changes..."); win.Close(vsSaveChanges.vsSaveChangesYes); @@ -270,14 +275,14 @@ namespace Tango.BuildExtensions foreach (var template in edmx.ProjectItems.OfType<ProjectItem>().Where(x => x.Name.EndsWith(".tt"))) { - SetProgressText("Running custom tool for " + template.Name + "..."); + SetVSProgress("Running custom tool for " + template.Name + "..."); (template.Object as VSProjectItem).RunCustomTool(); _window.WaitWhileBusy(); } _window.WaitWhileBusy(); - SetProgressText("Building project " + dalProjectName + "..."); + SetVSProgress("Building project " + dalProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); @@ -296,13 +301,13 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + observablesGeneratorProjectName); } - SetProgressText("Building project " + observablesGeneratorProjectName + "..."); + SetVSProgress("Building project " + observablesGeneratorProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); DTE.Solution.Properties.Item("StartupProject").Value = observablesGeneratorProjectName; - SetProgressText("Executing observables generator..."); + SetVSProgress("Executing observables generator..."); DTE.ExecuteCommand("Debug.Start"); @@ -317,7 +322,7 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + observablesProjectName); } - SetProgressText("Updating " + observablesProjectName + "..."); + SetVSProgress("Updating " + observablesProjectName + "..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(observablesProject.FileName), "*.cs", SearchOption.AllDirectories)) { @@ -325,13 +330,13 @@ namespace Tango.BuildExtensions if (parentFolderName != "Debug" && parentFolderName != "Release" && parentFolderName != "obj") { - SetProgressText("Adding/Updating file " + Path.GetFileName(file) + "..."); + SetVSProgress("Adding/Updating file " + Path.GetFileName(file) + "..."); observablesProject.ProjectItems.AddFromFile(file); Wait(10); } } - SetProgressText("Building project " + observablesProjectName + "..."); + SetVSProgress("Building project " + observablesProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", observablesProject.FullName, true); @@ -350,13 +355,13 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + pmrGeneratorProjectName); } - SetProgressText("Building project " + pmrGeneratorProjectName + "..."); + SetVSProgress("Building project " + pmrGeneratorProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); DTE.Solution.Properties.Item("StartupProject").Value = pmrGeneratorProjectName; - SetProgressText("Executing PMR generator..."); + SetVSProgress("Executing PMR generator..."); DTE.ExecuteCommand("Debug.Start"); @@ -374,7 +379,7 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + protoCliProjectName); } - SetProgressText("Building project " + protoCliProjectName + "..."); + SetVSProgress("Building project " + protoCliProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", protoProject.FullName, true); @@ -385,7 +390,7 @@ namespace Tango.BuildExtensions DTE.Solution.Properties.Item("StartupProject").Value = protoCliProjectName; - SetProgressText("Executing Tango Proto Compiler..."); + SetVSProgress("Executing Tango Proto Compiler..."); DTE.ExecuteCommand("Debug.Start"); @@ -401,7 +406,7 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + pmrProjectName); } - SetProgressText("Updating " + pmrProjectName + "..."); + SetVSProgress("Updating " + pmrProjectName + "..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(project.FileName), "*.cs", SearchOption.AllDirectories)) { @@ -409,13 +414,13 @@ namespace Tango.BuildExtensions if (parentFolderName != "Debug" && parentFolderName != "Release" && parentFolderName != "obj") { - SetProgressText("Adding/Updating file " + Path.GetFileName(file) + "..."); + SetVSProgress("Adding/Updating file " + Path.GetFileName(file) + "..."); project.ProjectItems.AddFromFile(file); Wait(10); } } - SetProgressText("Building project " + pmrProjectName + "..."); + SetVSProgress("Building project " + pmrProjectName + "..."); DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); @@ -425,9 +430,33 @@ namespace Tango.BuildExtensions } } + private void GenerateSQLite() + { + var project = _projects.SingleOrDefault(x => x.Name == sqliteProjectName); + + if (project == null) + { + throw new NullReferenceException("Could not locate project " + sqliteProjectName); + } + + SetVSProgress("Building project " + sqliteProjectName + "..."); + + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + + DTE.Solution.Properties.Item("StartupProject").Value = sqliteProjectName; + + SetVSProgress("Executing SQLite generator..."); + + DTE.ExecuteCommand("Debug.Start"); + + WaitForWindowOpen("Tango SQLite Generator"); + + WaitForWindowClose("Tango SQLite Generator"); + } + private void BuildSolution() { - SetProgressText("Building solution..."); + SetVSProgress("Building solution..."); DTE.Solution.SolutionBuild.Build(true); if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs index 50860cfa3..3957bbfdf 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs @@ -21,7 +21,6 @@ namespace Tango.BuildExtensions { public class VSIXBase { - private SelectForm _form; private IVsThreadedWaitDialog2 _vsProgress = null; public IServiceProvider BaseServiceProvider { get; private set; } @@ -155,7 +154,7 @@ namespace Tango.BuildExtensions VsShellUtilities.ShowMessageBox( BaseServiceProvider, text, - "Tango Initializer", + "Tango", OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); @@ -245,44 +244,6 @@ namespace Tango.BuildExtensions }); } - protected void OpenProgressForm() - { - System.Threading.Thread thread = new System.Threading.Thread(() => - { - _form = new SelectForm(); - var handle = _form.Handle; - _form.ShowDialog(); - }); - - thread.SetApartmentState(System.Threading.ApartmentState.STA); - thread.Start(); - - while (_form == null || !_form.IsHandleCreated) { } - } - - protected void SetProgressText(String text) - { - if (_form != null) - { - _form.Invoke(new Action(() => - { - _form.SetStatus(text); - })); - } - } - - protected void CloseProgressForm() - { - if (_form != null) - { - _form.Invoke(new Action(() => - { - _form.Close(); - _form = null; - })); - } - } - #endregion #region Content |
