From 733d5612fb7c1558ad0e28ebe2e2dd93477d07ed Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 20 Sep 2012 14:42:57 +0200 Subject: [PATCH] Change and Clone kit functionality Change-Id: Ibdab8d9076d2f9c002cb69ad81809929c8697355 Reviewed-by: Tobias Hunger --- .../analyzerruncontrolfactory.cpp | 8 + .../analyzerbase/analyzerruncontrolfactory.h | 1 + src/plugins/analyzerbase/analyzersettings.cpp | 20 +- src/plugins/analyzerbase/analyzersettings.h | 4 + .../projectexplorer/buildconfiguration.cpp | 13 + .../projectexplorer/buildconfiguration.h | 1 + .../projectexplorer/deployconfiguration.cpp | 14 +- .../projectexplorer/deployconfiguration.h | 1 + .../images/targetchangebutton.png | Bin 0 -> 1605 bytes .../images/targetchangebutton2.png | Bin 0 -> 1578 bytes .../images/targetremovebutton.png | Bin 566 -> 0 bytes .../images/targetremovebuttondark.png | Bin 1533 -> 0 bytes .../projectexplorer/projectexplorer.qrc | 4 +- .../projectexplorer/runconfiguration.cpp | 49 ++- .../projectexplorer/runconfiguration.h | 4 +- .../projectexplorer/targetselector.cpp | 125 ++++++-- src/plugins/projectexplorer/targetselector.h | 20 +- .../projectexplorer/targetsettingspanel.cpp | 283 +++++++++++++++--- .../projectexplorer/targetsettingspanel.h | 18 +- .../projectexplorer/targetsettingswidget.cpp | 9 +- .../projectexplorer/targetsettingswidget.h | 8 +- src/plugins/valgrind/valgrindsettings.cpp | 14 + src/plugins/valgrind/valgrindsettings.h | 2 + 23 files changed, 509 insertions(+), 89 deletions(-) create mode 100644 src/plugins/projectexplorer/images/targetchangebutton.png create mode 100644 src/plugins/projectexplorer/images/targetchangebutton2.png delete mode 100644 src/plugins/projectexplorer/images/targetremovebutton.png delete mode 100644 src/plugins/projectexplorer/images/targetremovebuttondark.png diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp b/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp index 30eaaee0b00..5cca2f00764 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp +++ b/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp @@ -92,6 +92,14 @@ IRunConfigurationAspect *AnalyzerRunControlFactory::createRunConfigurationAspect return new AnalyzerRunConfigurationAspect; } +IRunConfigurationAspect *AnalyzerRunControlFactory::cloneRunConfigurationAspect(IRunConfigurationAspect *source) +{ + AnalyzerRunConfigurationAspect *s = dynamic_cast(source); + if (!s) + return 0; + return new AnalyzerRunConfigurationAspect(s); +} + RunConfigWidget *AnalyzerRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration) { AnalyzerRunConfigWidget *ret = new AnalyzerRunConfigWidget; diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.h b/src/plugins/analyzerbase/analyzerruncontrolfactory.h index 081b00443fd..987e451f6ec 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.h +++ b/src/plugins/analyzerbase/analyzerruncontrolfactory.h @@ -54,6 +54,7 @@ public: ProjectExplorer::RunMode mode, QString *errorMessage); ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(); + ProjectExplorer::IRunConfigurationAspect *cloneRunConfigurationAspect(ProjectExplorer::IRunConfigurationAspect *source); ProjectExplorer::RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration); }; diff --git a/src/plugins/analyzerbase/analyzersettings.cpp b/src/plugins/analyzerbase/analyzersettings.cpp index 3f36ff21c98..b5c305d71fd 100644 --- a/src/plugins/analyzerbase/analyzersettings.cpp +++ b/src/plugins/analyzerbase/analyzersettings.cpp @@ -56,6 +56,11 @@ AnalyzerSettings::AnalyzerSettings(QObject *parent) { } +AnalyzerSettings::AnalyzerSettings(AnalyzerSettings *other) +{ + +} + QVariantMap AnalyzerSettings::defaults() const { QVariantMap map; @@ -151,7 +156,7 @@ void AnalyzerGlobalSettings::registerTool(IAnalyzerTool *tool) AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect() - : AnalyzerSettings(0), m_useGlobalSettings(true) + : AnalyzerSettings((QObject *)0), m_useGlobalSettings(true) { QList tools = AnalyzerManager::tools(); // add sub configs @@ -165,6 +170,19 @@ AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect() resetCustomToGlobalSettings(); } +AnalyzerRunConfigurationAspect::AnalyzerRunConfigurationAspect(AnalyzerRunConfigurationAspect *other) + : AnalyzerSettings(other), m_useGlobalSettings(other->m_useGlobalSettings) +{ + + foreach (AbstractAnalyzerSubConfig *config, other->m_customConfigurations) + m_customConfigurations.append(config->clone()); + + if (m_useGlobalSettings) + m_subConfigs = AnalyzerGlobalSettings::instance()->subConfigs(); + else + m_subConfigs = m_customConfigurations; +} + AnalyzerRunConfigurationAspect::~AnalyzerRunConfigurationAspect() { qDeleteAll(m_customConfigurations); diff --git a/src/plugins/analyzerbase/analyzersettings.h b/src/plugins/analyzerbase/analyzersettings.h index 843e4edf78b..09bbbbf8b19 100644 --- a/src/plugins/analyzerbase/analyzersettings.h +++ b/src/plugins/analyzerbase/analyzersettings.h @@ -80,6 +80,8 @@ public: virtual QString displayName() const = 0; /// create a configuration widget for this configuration virtual QWidget *createConfigWidget(QWidget *parent) = 0; + /// clones s AbstractAnalyzerSubConfig + virtual AbstractAnalyzerSubConfig *clone() = 0; }; /** @@ -117,6 +119,7 @@ protected: void fromMap(const QVariantMap &map, QList *subConfigs); AnalyzerSettings(QObject *parent); + AnalyzerSettings(AnalyzerSettings *other); QList m_subConfigs; }; @@ -165,6 +168,7 @@ class ANALYZER_EXPORT AnalyzerRunConfigurationAspect public: AnalyzerRunConfigurationAspect(); + AnalyzerRunConfigurationAspect(AnalyzerRunConfigurationAspect *other); ~AnalyzerRunConfigurationAspect(); QString displayName() const; diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 2a13c26c10f..eee87cbbc3e 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -282,6 +282,7 @@ IBuildConfigurationFactory::IBuildConfigurationFactory(QObject *parent) : IBuildConfigurationFactory::~IBuildConfigurationFactory() { } +// restore IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map) { QList factories @@ -293,6 +294,7 @@ IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, con return 0; } +// create IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) { QList factories @@ -304,4 +306,15 @@ IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) return 0; } +// clone +IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, BuildConfiguration *bc) +{ + QList factories + = ExtensionSystem::PluginManager::instance()->getObjects(); + foreach (IBuildConfigurationFactory *factory, factories) { + if (factory->canClone(parent, bc)) + return factory; + } + return 0; +} } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index be8e034e514..cb7ad748d94 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -145,6 +145,7 @@ public: static IBuildConfigurationFactory *find(Target *parent, const QVariantMap &map); static IBuildConfigurationFactory *find(Target *parent); + static IBuildConfigurationFactory *find(Target *parent, BuildConfiguration *bc); signals: void availableCreationIdsChanged(); diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp index f5db9d320b7..2c0796381a3 100644 --- a/src/plugins/projectexplorer/deployconfiguration.cpp +++ b/src/plugins/projectexplorer/deployconfiguration.cpp @@ -65,7 +65,8 @@ DeployConfiguration::DeployConfiguration(Target *target, const Core::Id id) : } DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) : - ProjectConfiguration(target, source) + ProjectConfiguration(target, source), + m_stepList(0) { Q_ASSERT(target); // Do not clone stepLists here, do that in the derived constructor instead @@ -256,6 +257,17 @@ DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent) return 0; } +DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, DeployConfiguration *dc) +{ + QList factories + = ExtensionSystem::PluginManager::instance()->getObjects(); + foreach (DeployConfigurationFactory *factory, factories) { + if (factory->canClone(parent, dc)) + return factory; + } + return 0; +} + bool DeployConfigurationFactory::canHandle(Target *parent) const { if (!parent->project()->supportsKit(parent->kit())) diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h index 49482879dc9..a5bef294d88 100644 --- a/src/plugins/projectexplorer/deployconfiguration.h +++ b/src/plugins/projectexplorer/deployconfiguration.h @@ -114,6 +114,7 @@ public: static DeployConfigurationFactory *find(Target *parent, const QVariantMap &map); static DeployConfigurationFactory *find(Target *parent); + static DeployConfigurationFactory *find(Target *parent, DeployConfiguration *dc); signals: void availableCreationIdsChanged(); diff --git a/src/plugins/projectexplorer/images/targetchangebutton.png b/src/plugins/projectexplorer/images/targetchangebutton.png new file mode 100644 index 0000000000000000000000000000000000000000..1311d38ef8a4996cf456b126c2d5467d2ca112c2 GIT binary patch literal 1605 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!tozhpW)2Y5O=D+Cnfr)B1( zGB8x!>YZ{vUnEuHxc%}CAMCVmnBcT6VFH_D`R>!(0#2vhPP#o~#@jcy z?{2(&^W)r`pOkG2FG{bdZ|IV-nNeYMFkVpafFm=fqjQdjkHwT9$}U2BZC4Kal(T0X z{r=_5=eqgtzyG#*Ke_SD^U(X{m&MLhEnGF_)3qN*mQ3C0I4eEE**tqy*@Ne&o+>u1 zdcWJI=-po*t_QciO@06W^O}_>542qocGxU-WAg+nwq4o3wOAgDZFrvXqJ2W8*o&aY z!jmVQWQzT&p~ny#9B9K=vht#reM-!MEz(z|Ql2%=Tj{cIUWYP2L&?-7>Qj@Wrv}~A zTK#Ox<5MknkH`E!Z~S`Ow6A82+08R2Iv)u0kj-Av=p|F16yB|TpnJluH|;;UHb@55 zZ%I2=bimBR-gGTrkL!;wtJS3z=QF)lh%G*J@S;Wiq1jS)GFO+KKV!llnsg@B`o(;f zdF@}$w#mqJ{mHnJvXJ9T!?u+dr8<6YZ9aI%qj2VPm&NrKk1k%ZzS^9+Kzhsf(9J~_ zpVrKsn72~sW48F;4Kmdi#B9qeG#-g8Kuz%yDCZZkzl=dzRt5N=2up=Iv?P>@V!_i)b&ydS7-0>S{VQ#f|=N z1ZyK6nSR`LL!V1Y``3|sWx19M^8=rk&3+ym<)Nb`qgcOd_tve8%Y*j5y%Fwrw{pR* zpB?Et->6$MGNs)*@%H3D{j>Gk7alH*om2h#)-CVPGIe)qzDECAR2RE{>HQ1hRvdrB zYaQb+Jesnlf6MwU@3*esn!iPUb8oLNvX!}*brf^($~%ZvP9$EOD8w_H1y z^G#Iy`R{dG*lera`$J1(y)D1GNkn+D1)V*4i|?4a+S(W5wcDMzJl5{Mbh0)7z`p$s zyKkNJ-S(iH;oAN?Cv)GnEw^tg-u-sktnU9mS6=ZK@OghrvUcs+=DOm{m+#U})Np*a zkBIv9{LH0Gf6qHaH++7#Ka!!a;%bOiAp-*gTavfC3&Vd9T(EcfWCjKX&H|6fVg?3o zVGw3ym^DX&fq{X&#M9T6{SK!HH^0K^2kfgE7#J^kx;TbdoSqx(z3P>NfbCtk<~FfO zodO)4lh-`nyKus8_PMF-kIhtvuU4Wr!CcO`M}s z7M*^YbxyHGUvbCdAFp{8cn;SFiZs6e{bCniXsDwXC&LUMwF{-PQ-V}HnJ$}D3oM%A zB+*u_=VN;gqHzuGs4f zU+?-CcinW8PV@812XojN9In0o`aQ+y=i#)zcR8 zH^#+YFP)N_neD_;zcIo=lhui1+il&tO&VPbra0Z+CgAi#gki~)z0Wkd>U`?1EXj@T zaZ?UB7Gb0lb9QQmw1eg3U>g+P&onX{J9ShXra!p&<+ zP{i7>Q`>R_ynZkFSaE0m>s@ufe6N>!ToyV0cwzuULG1Sl&wmOxPucYSI^UB@zU!s@ z`HO4p<};t(^dVDCZm)h9)3#ju{!axn{gwwGkT_go^)~fNY47c~Y>F(?PCtE~`s=OL bfA)&+d3psLrP~=87#KWV{an^LB{Ts5y~7m0 literal 0 HcmV?d00001 diff --git a/src/plugins/projectexplorer/images/targetchangebutton2.png b/src/plugins/projectexplorer/images/targetchangebutton2.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d5cfefd9df447b31a45c94121979b37e44412a GIT binary patch literal 1578 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!tozhpW)2Y5O=D+Cnfr)B1( zGB8x!>YZ{vUnEuHxc%}CAMCVmnBcT6VFH_D`R>!(0#2vhPP#o~#@jcy z?{2(&^W)r`pOkG2FG{bdZ|IV-nNeYMFkVpafFm=fqjQdjkHwT9$}U2BZC4Kal(T0X z{r=_5=eqgtzyG#*Ke_SD^U(X{m&MLhEnGF_)3qN*mQ3C0I4eEE**tqy*@Ne&o+>u1 zdcWJI=-po*t_QciO@06W^O}_>542qocGxU-WAg+nwq4o3wOAgDZFrvXqJ2W8*o&aY z!jmVQWQzT&p~ny#9B9K=vht#reM-!MEz(z|Ql2%=Tj{cIUWYP2L&?-7>Qj@Wrv}~A zTK#Ox<5MknkH`E!Z~S`Ow6A82+08R2Iv)u0kj-Av=p|F16yB|TpnJluH|;;UHb@55 zZ%I2=bimBR-gGTrkL!;wtJS3z=QF)lh%G*J@S;Wiq1jS)GFO+KKV!llnsg@B`o(;f zdF@}$w#mqJ{mHnJvXJ9T!?u+dr8<6YZ9aI%qj2VPm&NrKk1k%ZzS^9+Kzhsf(9J~_ zpVrKsn72~sW48F;4Kmdi#B9qeG#-g8Kuz%yDCZZkzl=dzRt5N=2up=Iv?P>@V!_i)b&ydS7-0>S{VQ#f|=N z1ZyK6nSR`LL!V1Y``3|sWx19M^8=rk&3+ym<)Nb`qgcOd_tve8%Y*j5y%Fwrw{pR* zpB?Et->6$MGNs)*@%H3D{j>Gk7alH*om2h#)-CVPGIe)qzDECAR2RE{>HQ1hRvdrB zYaQb+Jesnlf6MwU@3*esn!iPUb8oLNvX!}*brf^($~%ZvP9$EOD8w_H1y z^G#Iy`R{dG*lera`$J1(y)D1GNkn+D1)V*4i|?4a+S(W5wcDMzJl5{Mbh0)7z`p$s zyKkNJ-S(iH;oAN?Cv)GnEw^tg-u-sktnU9mS6=ZK@OghrvUcs+=DOm{m+#U})Np*a zkBIv9{LH0Gf6qHaH++7#Ka!!a;%bOiAp-*gTavfC3&Vd9T(EcfWCjKX&H|6fVg?3o zVGw3ym^DX&fq{X&#M9T6{SK!zpQfh1*Sl#942;`7T^vI!PS2g}z3P#JM617?tK5+j zy&_#lR%*XUJ(9blK}UuAgjtCypDeqe6654WK~XDL&D)~bRJ-#od)Bx4{lDao8y!nn zwMc_6=#&S?#%FW#85MXAZ+`z<+==7#=Nj|1+m|&g(%>tNO`j5Uq_D?;hmm1U@s`}~ zUF#e*ZT%FL7ie@bC+m1$7KzIC&@|*>W;jq9E8vuH+icY;ClOcWBSyy-XmmN>{~kGO z*^6C#UYa$N9$U;fo3>&Vm!p8pXPf($g);K5cAYbu&3kKG>ouwR$=9TuI8;2FR;}8$ z{PN4`x=VXBmL~K(T%Od^7{sNSn!>GktwrF^Y7RvKr!}$XetvuXn){eU#I)AGb^q6H z)bW-`UND8}c}+I+0RtX`V-DH9n{@V@X0JUSb$eT4dtyc1+SjHl{3lHRsj8`3bKm~< zzW4F-&a3wrKCYHrmbUat^jY}>M^#%kEX#aQDW`M#&}!A|rS2!bv@<01I9@M}(3_rP zvt(K3rk^$c7W3YDU#{X=bmnu-_p(#lZ|inHmgsw2W1_Y6LaD4+_tD>){)bEU#%)&M xcu*-9b6qyN!ba}JZ@JZ1Ulq^zXMS!!a3nI!GGi0g z)m?tPGfu$gUG1cN3(NPF`_1oLx=#$+bT-3e()sh}_w3zkDA&(;p>(d(LWiY64<9{p zx_M3eHrv`T?`^kp&z(PiGHvsc%b5&zc6J|Z`cI}ftqptp?3vq5;|vq2PhY=IJ$>4H zkw((iC_xrR26uP&j9G1~R`IYgcO6yw{{6dG&WA5wRB~^tO+Wqd-@kKJd!GrMOqq1~ za&X&W#kRzP^77>?w&kAA+uptIwMCz^M4N}^#2_J8!9bCtuMKz#W!Ph{zbxB*W1FsU zczAeyi$LKWXN^g&L~%@-+xBT`%=q7NpsvaHIRD^lUdLjztmLmyI<*Hug&8u*3H_Mm=JmG{_;HwZ|0oxTkfnj`QeWr z7IHZfZ8f#E8)Ni#?%Vh5+qbg+#<>-hl@s^I^*<~)QDVjV;LV$!7`^t)SyN6wo%{PA a+o^!MmVo?^FBljY7(8A5T-G@yGywq3UI$+Q diff --git a/src/plugins/projectexplorer/images/targetremovebuttondark.png b/src/plugins/projectexplorer/images/targetremovebuttondark.png deleted file mode 100644 index c1ec33f910809e563755c8b27a4e407258c9683c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1533 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!toKV&*P2Y5O=D+Cnfr)B1( zGB9XN>+6PzB4~&iJ1L@jeUHg-RnbxqjyS6tv$x(IeFa<@@3V2yJGa1 z^p3Togii%Y{+E@xJm=ads}TPyc5vti0g>vjAJ_uPJd(7f+>=cCOd zSv|Fmh{TF%k97_k%gFOv1i#Wqn%2GK`c|z+sz?4B8~)7U`7G14RoP$nmDH{?Re@!1 zXC+>W*ySJa|Ga6wS=7g>k1szxQ|o`UyZ>rj`SB|P_3N^CdLGeN-uLW>q*}e`$Gyj5 zRC_D*9X`#RRlVfU&y(h2uY=z!-0R$t^`muVz`l&LQ`C0k7FC|JTh%rvdzX2aZL_%G z{Z*HpCO%hon3`6+CcdNkb??Rt`wiad`aFxO6MMZ_^__dc{maKrcT@}1zqs{^<$Pqs zvb4CT|5~;C;`xdNuIX+Ld1BY;vUkBThj-VPAKRg8`QWi)QM6I4ai56Oze&k#n>%(+ z{G8{!wq=g=tl6iF?Vs3f)mnJ|%DPq4QuoTb)JXKHnk+~-%=6AFVgsYmiV5vJ`(z6O zgPECqrUYCGnj+D;JdrQ;ZROL3!-Yp?@UFQ&)6^~V{6oQaEi$u9gj?Snf3Bc8$vI_4 zPlL}rmHdf^Rk|+;78P9HCewXB>F&)hpY2R8Xg`*1KC^S4TfE5oHPx3ctgrv_T`c?e z#5tMT^DEd79Om0HgZbmH^?H9dXn)%1q_?Mf^XpeaJ~k`&ue`nT>lLndt5?kOsdo_@Q`^GC>!upfax{C>p!kW6_vsUY%)=MJSB<(QtiS06u5{`{u7 zD*CFC@9wx@gQY!NqN_YldFgws_c(fD{uNzb&*V#TSKi#S*`UHl9*MWF@NJIFGdwb9hUjI5?&_n0g&s2LJEqRx!CtDo zEdr!yq#0ndvllm``{_ppPJOIS`oA1 z%fY%xV_(aF%1z$3uk*M_OPC*I^Dp?l z)#F-w`J>JA8DlIKnBQsraL!+)j`2g*@9!V$V@&NH3O|6$*&A1n!vAE$ku|1_=m zvG$Ko*El$2?3)<(@cHwZ=HE6in{voH zZ1q+1=XcV3jxs#hmG{iTZ{OX#`u*3l&a<>kkX>rR*~BpUB+KKE5)1`9V+!o%J8HTL zu>3ah-CxDhG9flJ)Klj8grG(1vN;qP7^bBj+?M-dSD()52bK4lU4p$D1vVx3s20jB zUZu4q_x5I1hGm(DKHH>3vRyCzo;j=TC4+;e?;;JSK#`1DY+jlgOBI&3O!>4iZx)+t zphA~YfR`}Cg=wdsZcmNe?{oQ$=DoL>v##CFzAfg|VQ=;P&i35j3qQ%6cX^+9+sxwm zzLOH&%P+rtd?0P}&lmsuzE<%vyx7Ipv+)KCgW{3nX7&&Du9V919B$Yaq4TfLZE=Nx z#FsAK!xbX?ojDlKRW7scn|wcSyZn8}*y{x{>er_P%{c%3)c4vKyZ$XIdcP`j*7QA7 zgevDfF0jb3VrWU+p?`YQa;26Afko5xPYWeVyldPZXgAmIWQx(jFVdQ I&MBb@0IiMmHUIzs diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc index b36371d1069..85ea369bbe1 100644 --- a/src/plugins/projectexplorer/projectexplorer.qrc +++ b/src/plugins/projectexplorer/projectexplorer.qrc @@ -40,7 +40,7 @@ images/unconfigured.png images/targetleftbutton.png images/targetrightbutton.png - images/targetremovebutton.png - images/targetremovebuttondark.png + images/targetchangebutton.png + images/targetchangebutton2.png diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index c1784518429..4dd89915d5b 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -123,16 +123,17 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration m_suppressQmlDebuggingSpinbox(false) {} -DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other) : - m_runConfiguration(other->m_runConfiguration), - m_useCppDebugger(other->m_useCppDebugger), - m_useQmlDebugger(other->m_useQmlDebugger), - m_qmlDebugServerPort(other->m_qmlDebugServerPort), - m_useMultiProcess(other->m_useMultiProcess), - m_suppressDisplay(other->m_suppressDisplay), - m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), - m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), - m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) +DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, + DebuggerRunConfigurationAspect *other) + : m_runConfiguration(runConfiguration), + m_useCppDebugger(other->m_useCppDebugger), + m_useQmlDebugger(other->m_useQmlDebugger), + m_qmlDebugServerPort(other->m_qmlDebugServerPort), + m_useMultiProcess(other->m_useMultiProcess), + m_suppressDisplay(other->m_suppressDisplay), + m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), + m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), + m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) {} RunConfiguration *DebuggerRunConfigurationAspect::runConfiguration() @@ -284,10 +285,18 @@ RunConfiguration::RunConfiguration(Target *target, const Core::Id id) : RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) : ProjectConfiguration(target, source), - m_debuggerAspect(new DebuggerRunConfigurationAspect(source->debuggerAspect())) + m_debuggerAspect(new DebuggerRunConfigurationAspect(this, source->debuggerAspect())) { Q_ASSERT(target); - addExtraAspects(); + QList factories = ExtensionSystem::PluginManager::getObjects(); + foreach (IRunConfigurationAspect *aspect, source->m_aspects) { + foreach (IRunControlFactory *factory, factories) { + if (IRunConfigurationAspect *clone = factory->cloneRunConfigurationAspect(aspect)) { + m_aspects.append(clone); + break; + } + } + } } RunConfiguration::~RunConfiguration() @@ -455,6 +464,17 @@ IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, const Q return 0; } +IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, RunConfiguration *rc) +{ + QList factories + = ExtensionSystem::PluginManager::instance()->getObjects(); + foreach (IRunConfigurationFactory *factory, factories) { + if (factory->canClone(parent, rc)) + return factory; + } + return 0; +} + QList IRunConfigurationFactory::find(Target *parent) { QList factories @@ -505,6 +525,11 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect() return 0; } +IRunConfigurationAspect *IRunControlFactory::cloneRunConfigurationAspect(IRunConfigurationAspect *source) +{ + return 0; +} + RunConfigWidget *IRunControlFactory::createConfigurationWidget(RunConfiguration *) { return 0; diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 05e6b9163c2..337a1d0846d 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -91,7 +91,7 @@ class PROJECTEXPLORER_EXPORT DebuggerRunConfigurationAspect public: DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration); - DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other); + DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, DebuggerRunConfigurationAspect *other); enum QmlDebuggerStatus { DisableQmlDebugger = 0, @@ -214,6 +214,7 @@ public: virtual RunConfiguration *clone(Target *parent, RunConfiguration *product) = 0; static IRunConfigurationFactory *find(Target *parent, const QVariantMap &map); + static IRunConfigurationFactory *find(Target *parent, RunConfiguration *rc); static QList find(Target *parent); signals: @@ -235,6 +236,7 @@ public: virtual QString displayName() const = 0; virtual IRunConfigurationAspect *createRunConfigurationAspect(); + virtual IRunConfigurationAspect *cloneRunConfigurationAspect(IRunConfigurationAspect *); virtual RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration); }; diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index 25288ba1e4c..3b5e1272a47 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -37,10 +37,41 @@ #include #include #include +#include static const int TARGET_HEIGHT = 43; static const int NAVBUTTON_WIDTH = 27; +namespace ProjectExplorer { +namespace Internal { +class QPixmapButton : public QPushButton +{ +public: + QPixmapButton(QWidget *parent, const QPixmap &first, const QPixmap &second) + : QPushButton(parent), m_showFirst(true), m_first(first), m_second(second) + { + setFixedSize(m_first.size()); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_showFirst ? m_first : m_second); + } + + void setFirst(bool f) + { + m_showFirst = f; + } + +private: + bool m_showFirst; + const QPixmap m_first; + const QPixmap m_second; +}; +} +} + using namespace ProjectExplorer::Internal; TargetSelector::TargetSelector(QWidget *parent) : @@ -50,11 +81,12 @@ TargetSelector::TargetSelector(QWidget *parent) : m_buildselected(QLatin1String(":/projectexplorer/images/targetbuildselected.png")), m_targetRightButton(QLatin1String(":/projectexplorer/images/targetrightbutton.png")), m_targetLeftButton(QLatin1String(":/projectexplorer/images/targetleftbutton.png")), - m_targetRemoveButton(QLatin1String(":/projectexplorer/images/targetremovebutton.png")), - m_targetRemoveDarkButton(QLatin1String(":/projectexplorer/images/targetremovebuttondark.png")), + m_targetChangePixmap(QLatin1String(":/projectexplorer/images/targetchangebutton.png")), + m_targetChangePixmap2(QLatin1String(":/projectexplorer/images/targetchangebutton2.png")), m_currentTargetIndex(-1), m_currentHoveredTargetIndex(-1), - m_startIndex(0) + m_startIndex(0), + m_menuShown(false) { QFont f = font(); f.setPixelSize(10); @@ -62,6 +94,27 @@ TargetSelector::TargetSelector(QWidget *parent) : setFont(f); setMouseTracking(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_targetChangeButton = new QPixmapButton(this, m_targetChangePixmap2, m_targetChangePixmap); + m_targetChangeButton->hide(); + connect(m_targetChangeButton, SIGNAL(pressed()), this, SLOT(changeButtonPressed())); +} + +void TargetSelector::changeButtonPressed() +{ + emit menuShown(m_currentHoveredTargetIndex); +} + +void TargetSelector::menuAboutToShow() +{ + m_menuShown = true; + updateButtons(); +} + +void TargetSelector::menuAboutToHide() +{ + m_menuShown = false; + updateButtons(); } void TargetSelector::insertTarget(int index, const QString &name) @@ -137,6 +190,25 @@ TargetSelector::Target TargetSelector::targetAt(int index) const return m_targets.at(index); } +void TargetSelector::setTargetMenu(QMenu *menu) +{ + if (m_targetChangeButton->menu()) { + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } + + m_targetChangeButton->setMenu(menu); + + if (menu) { + connect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + connect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } +} + int TargetSelector::targetWidth() const { static int width = -1; @@ -158,7 +230,7 @@ int TargetSelector::maxVisibleTargets() const return (width() - ((NAVBUTTON_WIDTH + 1) * 2 + 3))/(targetWidth() + 1); } -void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton) +void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex) { if (buttonIndex) *buttonIndex = -1; @@ -166,8 +238,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd *targetIndex = -1; if (targetSubIndex) *targetSubIndex = -1; - if (removeButton) - *removeButton = false; // left button? if (m_startIndex > 0 /* button visible */ && x >= 0 && x < NAVBUTTON_WIDTH + 2) { @@ -197,6 +267,7 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd } --index; tx -= targetWidth() + 1; + if (index >= 0 && index < m_targets.size()) { if (targetIndex) *targetIndex = index; @@ -210,10 +281,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd if (targetSubIndex) *targetSubIndex = 0; } - } else if (y < m_targetRemoveButton.height() + 3 - && x >= tx + targetWidth() - m_targetRemoveButton.width() - 1) { - if (removeButton) - *removeButton = true; } } } @@ -223,8 +290,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) int buttonIndex; int targetIndex; int targetSubIndex; - bool removeButton; - getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex, &removeButton); + getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex); if (buttonIndex == 0) { event->accept(); --m_startIndex; @@ -236,7 +302,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) } else if (targetIndex != -1) { event->accept(); bool updateNeeded = false; - if (targetIndex != m_currentTargetIndex && !removeButton) { + if (targetIndex != m_currentTargetIndex) { m_currentTargetIndex = targetIndex; updateNeeded = true; } @@ -245,8 +311,6 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) m_targets[m_currentTargetIndex].currentSubIndex = targetSubIndex; updateNeeded = true; } - } else if (removeButton) { - emit removeButtonClicked(targetIndex); } if (updateNeeded) { update(); @@ -260,11 +324,12 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) void TargetSelector::mouseMoveEvent(QMouseEvent *event) { int targetIndex; - getControlAt(event->x(), event->y(), 0, &targetIndex, 0, 0); + getControlAt(event->x(), event->y(), 0, &targetIndex, 0); if (m_currentHoveredTargetIndex != targetIndex) { m_currentHoveredTargetIndex = targetIndex; if (targetIndex != -1) event->accept(); + updateButtons(); update(); } } @@ -273,18 +338,34 @@ void TargetSelector::leaveEvent(QEvent *event) { Q_UNUSED(event) m_currentHoveredTargetIndex = -1; + updateButtons(); update(); } +void TargetSelector::updateButtons() +{ + if (m_menuShown) { + // Do nothing while the menu is show + } else if (m_currentHoveredTargetIndex == -1) { + m_targetChangeButton->hide(); + } else { + int tx = NAVBUTTON_WIDTH + 3 + (m_currentHoveredTargetIndex - m_startIndex) * (targetWidth() + 1); + + QPoint buttonTopLeft(tx + targetWidth() - m_targetChangePixmap.width() - 1, 3); + m_targetChangeButton->move(buttonTopLeft); + m_targetChangeButton->setVisible(true); + m_targetChangeButton->setFirst(m_currentHoveredTargetIndex == m_currentTargetIndex); + } +} + bool TargetSelector::event(QEvent *e) { if (e->type() == QEvent::ToolTip) { const QHelpEvent *helpEvent = static_cast(e); int targetIndex; int subTargetIndex; - bool removeButton; - getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex, &removeButton); - if (targetIndex >= 0 && subTargetIndex < 0 && !removeButton) { + getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex); + if (targetIndex >= 0 && subTargetIndex < 0) { emit toolTipRequested(helpEvent->globalPos(), targetIndex); e->accept(); return true; @@ -341,12 +422,6 @@ void TargetSelector::paintEvent(QPaintEvent *event) p.drawText(x + (targetWidth()- fm.width(nameText))/2 + 1, 7 + fm.ascent(), nameText); - // remove button - if (m_currentHoveredTargetIndex == index) { - p.drawPixmap(x + targetWidth() - m_targetRemoveButton.width() - 2, 3, - index == m_currentTargetIndex ? m_targetRemoveDarkButton : m_targetRemoveButton); - } - // Build int margin = 2; // position centered within the rounded buttons QFontMetrics fm = fontMetrics(); diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h index 874f8207654..f69b13a3ed7 100644 --- a/src/plugins/projectexplorer/targetselector.h +++ b/src/plugins/projectexplorer/targetselector.h @@ -36,10 +36,12 @@ QT_BEGIN_NAMESPACE class QMenu; +class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { namespace Internal { +class QPixmapButton; class TargetSelector : public QWidget { @@ -63,6 +65,8 @@ public: int currentIndex() const { return m_currentTargetIndex; } int currentSubIndex() const { return m_targets.at(m_currentTargetIndex).currentSubIndex; } + void setTargetMenu(QMenu *menu); + public: void insertTarget(int index, const QString &name); void renameTarget(int index, const QString &name); @@ -71,11 +75,11 @@ public: void setCurrentSubIndex(int subindex); signals: - void removeButtonClicked(int targetIndex); // This signal is emitted whenever the target pointed to by the indices // has changed. void currentChanged(int targetIndex, int subIndex); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void paintEvent(QPaintEvent *event); @@ -84,8 +88,13 @@ protected: void leaveEvent(QEvent *event); bool event(QEvent *e); +private slots: + void changeButtonPressed(); + void updateButtons(); + void menuAboutToShow(); + void menuAboutToHide(); private: - void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton); + void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex); int maxVisibleTargets() const; const QImage m_unselected; @@ -93,14 +102,17 @@ private: const QImage m_buildselected; const QPixmap m_targetRightButton; const QPixmap m_targetLeftButton; - const QPixmap m_targetRemoveButton; - const QPixmap m_targetRemoveDarkButton; + const QPixmap m_targetChangePixmap; + const QPixmap m_targetChangePixmap2; + + QPixmapButton *m_targetChangeButton; QList m_targets; int m_currentTargetIndex; int m_currentHoveredTargetIndex; int m_startIndex; + bool m_menuShown; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index b8075e71e0a..c07e305a061 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -45,6 +45,9 @@ #include #include #include +#include +#include +#include #include #include @@ -70,6 +73,8 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_project(project), m_selector(0), m_centralWidget(0), + m_changeMenu(0), + m_duplicateMenu(0), m_lastAction(0) { Q_ASSERT(m_project); @@ -78,6 +83,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_panelWidgets[1] = 0; m_addMenu = new QMenu(this); + m_targetMenu = new QMenu(this); setFocusPolicy(Qt::NoFocus); @@ -92,7 +98,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : this, SLOT(activeTargetChanged(ProjectExplorer::Target*))); connect(KitManager::instance(), SIGNAL(kitsChanged()), - this, SLOT(updateTargetAddAndRemoveButtons())); + this, SLOT(updateTargetButtons())); } TargetSettingsPanelWidget::~TargetSettingsPanelWidget() @@ -102,21 +108,35 @@ TargetSettingsPanelWidget::~TargetSettingsPanelWidget() bool TargetSettingsPanelWidget::event(QEvent *event) { if (event->type() == QEvent::StatusTip) { + QAction *act = 0; + QMenu *menu = 0; + if (m_addMenu->activeAction()) { + menu = m_addMenu; + act = m_addMenu->activeAction(); + } else if (m_changeMenu && m_changeMenu->activeAction()) { + menu = m_changeMenu; + act = m_changeMenu->activeAction(); + } else if (m_duplicateMenu && m_duplicateMenu->activeAction()) { + menu = m_duplicateMenu; + act = m_duplicateMenu->activeAction(); + } else { + return QWidget::event(event); + } + QStatusTipEvent *ev = static_cast(event); ev->accept(); - QAction *act = m_addMenu->activeAction(); if (act != m_lastAction) QToolTip::showText(QPoint(), QString()); m_lastAction = act; if (act) { - QRect actionRect = m_addMenu->actionGeometry(act); - actionRect.translate(m_addMenu->pos()); + QRect actionRect = menu->actionGeometry(act); + actionRect.translate(menu->pos()); QPoint p = QCursor::pos(); if (!actionRect.contains(p)) p = actionRect.center(); p.setY(actionRect.center().y()); - QToolTip::showText(p, ev->tip(), m_addMenu, m_addMenu->actionGeometry(act)); + QToolTip::showText(p, ev->tip(), menu, menu->actionGeometry(act)); } else { QToolTip::showText(QPoint(), QString()); } @@ -169,18 +189,20 @@ void TargetSettingsPanelWidget::setupUi() connect(m_selector, SIGNAL(currentChanged(int,int)), this, SLOT(currentTargetChanged(int,int))); - connect(m_selector, SIGNAL(removeButtonClicked(int)), - this, SLOT(removeTarget(int))); connect(m_selector, SIGNAL(manageButtonClicked()), this, SLOT(openTargetPreferences())); connect(m_selector, SIGNAL(toolTipRequested(QPoint,int)), this, SLOT(showTargetToolTip(QPoint,int))); + connect(m_selector, SIGNAL(menuShown(int)), + this, SLOT(menuShown(int))); + + connect(m_addMenu, SIGNAL(triggered(QAction*)), + this, SLOT(addActionTriggered(QAction*))); m_selector->setAddButtonMenu(m_addMenu); - connect(m_addMenu, SIGNAL(triggered(QAction*)), - this, SLOT(addTarget(QAction*))); + m_selector->setTargetMenu(m_targetMenu); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subIndex) @@ -243,7 +265,36 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd m_project->setActiveTarget(target); } -void TargetSettingsPanelWidget::addTarget(QAction *action) +void TargetSettingsPanelWidget::menuShown(int targetIndex) +{ + m_menuTargetIndex = targetIndex; +} + +void TargetSettingsPanelWidget::changeActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value()); + Target *sourceTarget = m_targets.at(m_menuTargetIndex); + Target *newTarget = cloneTarget(sourceTarget, k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + m_project->removeTarget(sourceTarget); + } +} + +void TargetSettingsPanelWidget::duplicateActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value()); + Target *newTarget = cloneTarget(m_targets.at(m_menuTargetIndex), k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + } +} + +void TargetSettingsPanelWidget::addActionTriggered(QAction *action) { Kit *k = KitManager::instance()->find(action->data().value()); QTC_ASSERT(!m_project->target(k), return); @@ -254,10 +305,146 @@ void TargetSettingsPanelWidget::addTarget(QAction *action) m_project->addTarget(target); } -void TargetSettingsPanelWidget::removeTarget(int targetIndex) +Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k) { - Target *t = m_targets.at(targetIndex); + Target *newTarget = new Target(m_project, k); + QStringList buildconfigurationError; + QStringList deployconfigurationError; + QStringList runconfigurationError; + + foreach (BuildConfiguration *sourceBc, sourceTarget->buildConfigurations()) { + IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(newTarget, sourceBc); + if (!factory) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + BuildConfiguration *newBc = factory->clone(newTarget, sourceBc); + if (!newBc) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + newBc->setDisplayName(sourceBc->displayName()); + newTarget->addBuildConfiguration(newBc); + if (sourceTarget->activeBuildConfiguration() == sourceBc) + newTarget->setActiveBuildConfiguration(newBc); + } + if (!newTarget->activeBuildConfiguration()) { + QList bcs = newTarget->buildConfigurations(); + if (!bcs.isEmpty()) + newTarget->setActiveBuildConfiguration(bcs.first()); + } + + foreach (DeployConfiguration *sourceDc, sourceTarget->deployConfigurations()) { + DeployConfigurationFactory *factory = DeployConfigurationFactory::find(newTarget, sourceDc); + if (!factory) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + DeployConfiguration *newDc = factory->clone(newTarget, sourceDc); + if (!newDc) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + newDc->setDisplayName(sourceDc->displayName()); + newTarget->addDeployConfiguration(newDc); + if (sourceTarget->activeDeployConfiguration() == sourceDc) + newTarget->setActiveDeployConfiguration(newDc); + } + if (!newTarget->activeBuildConfiguration()) { + QList dcs = newTarget->deployConfigurations(); + if (!dcs.isEmpty()) + newTarget->setActiveDeployConfiguration(dcs.first()); + } + + foreach (RunConfiguration *sourceRc, sourceTarget->runConfigurations()) { + IRunConfigurationFactory *factory = IRunConfigurationFactory::find(newTarget, sourceRc); + if (!factory) { + runconfigurationError << sourceRc->displayName(); + continue; + } + RunConfiguration *newRc = factory->clone(newTarget, sourceRc); + if (!newRc) { + runconfigurationError << sourceRc->displayName(); + continue; + } + newRc->setDisplayName(sourceRc->displayName()); + newTarget->addRunConfiguration(newRc); + if (sourceTarget->activeRunConfiguration() == sourceRc) + newTarget->setActiveRunConfiguration(newRc); + } + if (!newTarget->activeRunConfiguration()) { + QList rcs = newTarget->runConfigurations(); + if (!rcs.isEmpty()) + newTarget->setActiveRunConfiguration(rcs.first()); + } + + bool fatalError = false; + if (buildconfigurationError.count() == sourceTarget->buildConfigurations().count()) + fatalError = true; + + if (deployconfigurationError.count() == sourceTarget->deployConfigurations().count()) + fatalError = true; + + if (runconfigurationError.count() == sourceTarget->runConfigurations().count()) + fatalError = true; + + if (fatalError) { + // That could be a more granular error message + QMessageBox::critical(Core::ICore::mainWindow(), + tr("Incompatible Kit"), + tr("The Kit %1 is incompatible with Kit %2.") + .arg(sourceTarget->kit()->displayName()) + .arg(k->displayName())); + + delete newTarget; + newTarget = 0; + } else if (!buildconfigurationError.isEmpty() + || !deployconfigurationError.isEmpty() + || ! runconfigurationError.isEmpty()) { + + QString error; + if (!buildconfigurationError.isEmpty()) + error += tr("Build configurations:\n") + + buildconfigurationError.join(QLatin1String("\n")); + + if (!deployconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Deploy configurations:\n") + + deployconfigurationError.join(QLatin1String("\n")); + } + + if (!runconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Run configurations ") + + runconfigurationError.join(QLatin1String("\n")); + } + + QMessageBox msgBox(Core::ICore::mainWindow()); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Partial Incompatible Kit")); + msgBox.setText(tr("Some configurations could not be copied.")); + msgBox.setDetailedText(error); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + if (msgBox.exec() != QDialog::Accepted) { + delete newTarget; + newTarget = 0; + } + } + + return newTarget; +} + +void TargetSettingsPanelWidget::removeTarget() +{ + Target *t = m_targets.at(m_menuTargetIndex); + removeTarget(t); +} + +void TargetSettingsPanelWidget::removeTarget(Target *t) +{ ProjectExplorer::BuildManager *bm = ProjectExplorerPlugin::instance()->buildManager(); if (bm->isBuilding(t)) { QMessageBox box; @@ -308,7 +495,7 @@ void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target) } connect(target, SIGNAL(displayNameChanged()), this, SLOT(renameTarget())); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) @@ -323,7 +510,7 @@ void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) m_selector->removeTarget(index); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *target) @@ -334,37 +521,61 @@ void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *tar m_selector->setCurrentIndex(index); } -void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons() +namespace { +bool diplayNameSorter(Kit *a, Kit *b) +{ + return a->displayName() < b->displayName(); +} +} + +void TargetSettingsPanelWidget::createAction(Kit *k, QMenu *menu) +{ + QAction *action = new QAction(k->displayName(), menu); + action->setData(QVariant::fromValue(k->id())); + QString errorMessage; + if (!m_project->supportsKit(k, &errorMessage)) { + action->setEnabled(false); + action->setStatusTip(errorMessage); + } + menu->addAction(action); +} + +void TargetSettingsPanelWidget::updateTargetButtons() { if (!m_selector) return; m_addMenu->clear(); + m_targetMenu->clear(); - foreach (Kit *k, KitManager::instance()->kits()) { + m_changeMenu = m_targetMenu->addMenu(tr("Change Kit")); + m_duplicateMenu = m_targetMenu->addMenu(tr("Copy to Kit")); + QAction *removeAction = m_targetMenu->addAction(tr("Remove Kit")); + + if (m_project->targets().size() < 2) + removeAction->setEnabled(false); + + connect(m_changeMenu, SIGNAL(triggered(QAction*)), + this, SLOT(changeActionTriggered(QAction*))); + connect(m_duplicateMenu, SIGNAL(triggered(QAction*)), + this, SLOT(duplicateActionTriggered(QAction*))); + connect(removeAction, SIGNAL(triggered()), this, SLOT(removeTarget())); + + QList kits = KitManager::instance()->kits(); + qSort(kits.begin(), kits.end(), diplayNameSorter); + foreach (Kit *k, kits) { if (m_project->target(k)) continue; - - QAction *action = new QAction(k->displayName(), m_addMenu); - action->setData(QVariant::fromValue(k->id())); - QString errorMessage; - if (!m_project->supportsKit(k, &errorMessage)) { - action->setEnabled(false); - action->setStatusTip(errorMessage); - } - - bool inserted = false; - foreach (QAction *existing, m_addMenu->actions()) { - if (existing->text() > action->text()) { - m_addMenu->insertAction(existing, action); - inserted = true; - break; - } - } - if (!inserted) - m_addMenu->addAction(action); + createAction(k, m_addMenu); + createAction(k, m_changeMenu); + createAction(k, m_duplicateMenu); } + if (m_changeMenu->actions().isEmpty()) + m_changeMenu->setEnabled(false); + if (m_duplicateMenu->actions().isEmpty()) + m_duplicateMenu->setEnabled(false); + m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty()); } diff --git a/src/plugins/projectexplorer/targetsettingspanel.h b/src/plugins/projectexplorer/targetsettingspanel.h index 4d78e58738a..5f93c6785b2 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.h +++ b/src/plugins/projectexplorer/targetsettingspanel.h @@ -43,6 +43,7 @@ namespace ProjectExplorer { class Target; class Project; +class Kit; namespace Internal { @@ -65,17 +66,24 @@ protected: bool event(QEvent *event); private slots: void currentTargetChanged(int targetIndex, int subIndex); - void removeTarget(int targetIndex); void showTargetToolTip(const QPoint &globalPos, int targetIndex); - void addTarget(QAction *); void targetAdded(ProjectExplorer::Target *target); void removedTarget(ProjectExplorer::Target *target); void activeTargetChanged(ProjectExplorer::Target *target); - void updateTargetAddAndRemoveButtons(); + void updateTargetButtons(); void renameTarget(); void openTargetPreferences(); + void removeTarget(); + void menuShown(int targetIndex); + void addActionTriggered(QAction *action); + void changeActionTriggered(QAction *action); + void duplicateActionTriggered(QAction *action); private: + Target *cloneTarget(Target *sourceTarget, Kit *k); + void removeTarget(Target *t); + void createAction(Kit *k, QMenu *menu); + Target *m_currentTarget; Project *m_project; TargetSettingsWidget *m_selector; @@ -83,8 +91,12 @@ private: QWidget *m_noTargetLabel; PanelsWidget *m_panelWidgets[2]; QList m_targets; + QMenu *m_targetMenu; + QMenu *m_changeMenu; + QMenu *m_duplicateMenu; QMenu *m_addMenu; QAction *m_lastAction; + int m_menuTargetIndex; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 1b6c8cd5b0e..90e28844604 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -63,12 +63,12 @@ TargetSettingsWidget::TargetSettingsWidget(QWidget *parent) : headerLayout->addWidget(m_targetSelector, 0, Qt::AlignBottom); headerLayout->addStretch(10); - connect(m_targetSelector, SIGNAL(removeButtonClicked(int)), - this, SIGNAL(removeButtonClicked(int))); connect(m_targetSelector, SIGNAL(currentChanged(int,int)), this, SIGNAL(currentChanged(int,int))); connect(m_targetSelector, SIGNAL(toolTipRequested(QPoint,int)), this, SIGNAL(toolTipRequested(QPoint,int))); + connect(m_targetSelector, SIGNAL(menuShown(int)), + this, SIGNAL(menuShown(int))); QPalette shadowPal = palette(); QLinearGradient grad(0, 0, 0, 2); @@ -119,6 +119,11 @@ void TargetSettingsWidget::setAddButtonMenu(QMenu *menu) m_addButton->setMenu(menu); } +void TargetSettingsWidget::setTargetMenu(QMenu *menu) +{ + m_targetSelector->setTargetMenu(menu); +} + QString TargetSettingsWidget::targetNameAt(int index) const { return m_targetSelector->targetAt(index).name; diff --git a/src/plugins/projectexplorer/targetsettingswidget.h b/src/plugins/projectexplorer/targetsettingswidget.h index 4650b878fdb..3918987c50e 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.h +++ b/src/plugins/projectexplorer/targetsettingswidget.h @@ -39,6 +39,8 @@ class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { +class Target; +class Kit; namespace Internal { namespace Ui { @@ -67,12 +69,14 @@ public: void setCurrentSubIndex(int index); void setAddButtonEnabled(bool enabled); void setAddButtonMenu(QMenu *menu); - + void setTargetMenu(QMenu *menu); signals: - void removeButtonClicked(int targetIndex); void currentChanged(int targetIndex, int subIndex); void manageButtonClicked(); + void duplicateButtonClicked(); + void changeKitButtonClicked(); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void changeEvent(QEvent *e); diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index fa7ff9f1d68..062d79c8250 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -326,6 +326,13 @@ void ValgrindGlobalSettings::fromMap(const QVariantMap &map) setIfPresent(map, QLatin1String(callgrindShortenTemplates), &m_shortenTemplates); } +AbstractAnalyzerSubConfig *ValgrindGlobalSettings::clone() +{ + ValgrindGlobalSettings *other = new ValgrindGlobalSettings; + other->fromMap(toMap()); + return other; +} + QVariantMap ValgrindGlobalSettings::toMap() const { QVariantMap map = ValgrindBaseSettings::toMap(); @@ -459,6 +466,13 @@ void ValgrindProjectSettings::fromMap(const QVariantMap &map) setIfPresent(map, removedSuppressionFilesC, &m_disabledGlobalSuppressionFiles); } +AbstractAnalyzerSubConfig *ValgrindProjectSettings::clone() +{ + ValgrindProjectSettings *other = new ValgrindProjectSettings; + other->fromMap(toMap()); + return other; +} + QVariantMap ValgrindProjectSettings::toMap() const { QVariantMap map = ValgrindBaseSettings::toMap(); diff --git a/src/plugins/valgrind/valgrindsettings.h b/src/plugins/valgrind/valgrindsettings.h index f835abc84e6..2c19fd62617 100644 --- a/src/plugins/valgrind/valgrindsettings.h +++ b/src/plugins/valgrind/valgrindsettings.h @@ -175,6 +175,7 @@ public: QVariantMap toMap() const; QVariantMap defaults() const; void fromMap(const QVariantMap &map); + virtual AbstractAnalyzerSubConfig *clone(); /* * Global memcheck settings @@ -232,6 +233,7 @@ public: QVariantMap toMap() const; QVariantMap defaults() const; void fromMap(const QVariantMap &map); + virtual AbstractAnalyzerSubConfig *clone(); /** * Per-project memcheck settings, saves a diff to the global suppression files list